HDU ACM 2234 无题I->IDA*算法

来源:互联网 发布:完美世界 小说 知乎 编辑:程序博客网 时间:2024/05/26 14:11

分析: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>using namespace std;int map[5][5];int deep;#define max(a,b) ((a)>(b)?(a):(b))#define min(a,b) ((a)<(b)?(a):(b))bool check()         //检查是否是合法状态{int i,j;if(map[1][1]!=map[1][2]){for(i=1;i<=4;i++)for(j=1;j<=4;j++)if(map[j][i]!=map[i][i])return false;}else{for(i=1;i<=4;i++)for(j=1;j<=4;j++)if(map[i][j]!=map[i][i])return false;}return true;}int get_h()         //IDA*的估价函数,获取每行或每列不在合法位置的数量{int r=0,c=0,i,j;for(i=1;i<=4;i++)         //每行{int ans=0;int h[5]={0};for(j=1;j<=4;j++) h[map[i][j]]++;for(j=1;j<=4;j++)ans=max(ans,h[j]);r=max(4-ans,r);}for(j=1;j<=4;j++)         //每列{int ans=0;int h[5]={0};for(i=1;i<=4;i++) h[map[i][j]]++;for(i=1;i<=4;i++)ans=max(ans,h[i]);c=max(4-ans,c);}return min(r,c);}void mov_l(int i){int j,t;t=map[i][1];for(j=2;j<=4;j++)map[i][j-1]=map[i][j];map[i][4]=t;}void mov_r(int i){int j,t;t=map[i][4];for(j=4;j>=2;j--)map[i][j]=map[i][j-1];map[i][1]=t;}void mov_u(int j){int i,t;t=map[1][j];for(i=2;i<=4;i++)map[i-1][j]=map[i][j];map[4][j]=t;}void mov_d(int j){int i,t;t=map[4][j];for(i=4;i>=2;i--)map[i][j]=map[i-1][j];map[1][j]=t;}bool IDA_Star(int step){int i;if(step==deep)return check();if(step+get_h()>deep)   //估价函数剪枝return false;for(i=1;i<=4;i++)      //每行{mov_l(i);if(IDA_Star(step+1))return true;mov_r(i);           //恢复mov_r(i);if(IDA_Star(step+1))return true;mov_l(i);           //恢复}for(i=1;i<=4;i++)      //每列{mov_u(i);if(IDA_Star(step+1))return true;mov_d(i);           //恢复mov_d(i);if(IDA_Star(step+1))return true;mov_u(i);           //恢复}return false;}int main()      {int t,i,j;cin>>t;while(t--){for(i=1;i<=4;i++)for(j=1;j<=4;j++)cin>>map[i][j];if(check())              //判断开始是否合法{cout<<"0"<<endl;continue;}deep=1;while(deep<=5){if(IDA_Star(0))break;deep++;}if(deep<=5)cout<<deep<<endl;elsecout<<"-1"<<endl;}    return 0;      }


0 0