您的位置:首页 > 其它

hdu 2234(IDA*)

2013-09-17 20:06 239 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2234

思路:IDA*可以搞,借鉴的是大牛的启发式函数h(): 可以考虑把每一行上的数转化成相同的,或者把每一列上的数字转化成相同的,二者取最小值。

1 1 3 2

2 4 4 2

3 3 1 4

1 2 3 4

如果把这个矩阵转化成行相同的话需要的操作:第一行 至少要2次,第二行也是2次, 第三行是2次,第四行是3次, 所以把矩阵转化成行相同至少要3次。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int map[5][5];
int maxdeep;

bool Judge()
{
if(map[1][1]!=map[1][2]){
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)
if(map[j][i]!=map[i][i])return false;
return true;
}else {
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)
if(map[i][j]!=map[i][1])return false;
return true;
}
}

int Get_H()
{
int step1=0,step2=0;
for(int i=1;i<=4;i++){
int num[5]={0},ans=0;
for(int j=1;j<=4;j++)num[map[i][j]]++;
for(int j=1;j<=4;j++)ans=max(ans,num[j]);
step1=max(step1,4-ans);
}
for(int j=1;j<=4;j++){
int num[5]={0},ans=0;
for(int i=1;i<=4;i++)num[map[i][j]]++;
for(int i=1;i<=4;i++)ans=max(ans,num[i]);
step2=max(step2,4-ans);
}
return min(step1,step2);
}

void Move_L(int i)
{
int tmp=map[i][1];
for(int j=2;j<=4;j++)map[i][j-1]=map[i][j];
map[i][4]=tmp;
}

void Move_R(int i)
{
int tmp=map[i][4];
for(int j=4;j>=2;j--)map[i][j]=map[i][j-1];
map[i][1]=tmp;
}

void Move_U(int j)
{
int tmp=map[1][j];
for(int i=2;i<=4;i++)map[i-1][j]=map[i][j];
map[4][j]=tmp;
}

void Move_D(int j)
{
int tmp=map[4][j];
for(int i=4;i>=2;i--)map[i][j]=map[i-1][j];
map[1][j]=tmp;
}

bool IDA_star(int deep)
{
if(deep==maxdeep)return Judge();
if(Get_H()+deep>maxdeep)return false;

for(int i=1;i<=4;i++){
Move_L(i);
if(IDA_star(deep+1))return true;
Move_R(i);

Move_R(i);
if(IDA_star(deep+1))return true;
Move_L(i);
}
for(int j=1;j<=4;j++){
Move_U(j);
if(IDA_star(deep+1))return true;
Move_D(j);

Move_D(j);
if(IDA_star(deep+1))return true;
Move_U(j);
}
return false;
}

int main()
{
int _case;
scanf("%d",&_case);
while(_case--){
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)scanf("%d",&map[i][j]);
if(Judge()){
puts("0");
continue;
}
maxdeep=1;
while(maxdeep<=5){
if(IDA_star(0))break;
maxdeep++;
}
if(maxdeep<=5){
printf("%d\n",maxdeep);
}else
puts("-1");
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: