BNUOJ 6378 无题I

无题I

Time Limit: 10000ms
Memory Limit: 32768KB
This problem will be judged on HDU. Original ID: 2234
64-bit integer IO format: %I64d      Java class name: Main
 
一天机器人小A在玩一个简单的智力游戏,这个游戏是这样的,在一个4*4的矩阵中分别有4个1,4个2,4个3和4个4分别表示4种不同的东西,每一步小A可以把同一行的4个数往左移或者往右移一步或者把同一列的4个数字往上移或者往下移一步(1,2,3,4往左移后是2,3,4,1),小A现在想知道进过最少的几步移动可以将矩阵的每行上的4个数字都一样或者每列上的4个数字都一样。但是小A又不想走太多步,他只要知道最少步数是否少于等于5步,是的话输出准确的步数,否则输出-1。
 

Input

先输入一个整数T,表示有T组数据。
对于每组数据输入4行,每行4列表示这个矩阵。
 

Output

对于每组输入输出一个正整数表示最少的移动步数,大于5则输出-1.
 

Sample Input

2

1 2 3 4
1 2 3 4
1 2 3 4
2 3 4 1

4 1 1 1
1 2 2 2
2 3 3 3
3 4 4 4

Sample Output

1
1

Source

 
 
 
解题:IDA*
 
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <climits>
 7 #include <vector>
 8 #include <queue>
 9 #include <cstdlib>
10 #include <string>
11 #include <set>
12 #define LL long long
13 #define INF 0x3f3f3f3f
14 using namespace std;
15 int g[4][4],ans;
16 bool check(int (*t)[4]){
17     int i,j;
18     bool flag = false;
19     for(i = 0; i < 4; i++){
20         for(j = 1; j < 4; j++)
21         if(t[j][i] != t[j-1][i]) {flag = true;break;}//检查每一列
22         if(flag) break;
23     }
24     if(!flag) return true;
25     for(i = 0; i < 4; i++){
26         for(j = 1; j < 4; j++)
27         if(t[i][j] != t[i][j-1]) {flag = false;break;}
28         if(!flag) break;
29     }
30     return flag;
31 }
32 void shift(int (*t)[4],int dir,int u){
33     int i,temp;
34     if(dir == 0){//行左移
35         temp = t[u][0];
36         for(i = 0; i < 3; i++)
37             t[u][i] = t[u][i+1];
38         t[u][i] = temp;
39     }else if(dir == 1){//行右移
40         temp = t[u][3];
41         for(i = 3; i; i--)
42             t[u][i] = t[u][i-1];
43         t[u][i] = temp;
44     }else if(dir == 2){//列上移
45         temp = t[0][u];
46         for(i = 0; i < 3; i++)
47             t[i][u] = t[i+1][u];
48         t[i][u] = temp;
49     }else if(dir == 3){//列下移
50         temp = t[3][u];
51         for(i = 3; i; i--)
52             t[i][u] = t[i-1][u];
53         t[i][u] = temp;
54     }
55 }
56 
57 bool dfs(int (*t)[4],int step){
58     int mp[4][4],i,j,k;
59     if(ans == step && check(t)) return true;
60     if(ans <= step) return false;
61     for(i = 0; i < 4; i++){
62         for(j = 0; j < 4; j++){
63             memcpy(mp,t,sizeof(mp));
64             shift(mp,j,i);
65             if(dfs(mp,step+1)) return true;
66         }
67     }
68     return false;
69 }
70 int main(){
71     int ks,i,j;
72     scanf("%d",&ks);
73     while(ks--){
74         for(i = 0; i < 4; i++){
75             for(j = 0; j < 4; j++)
76                 scanf("%d",g[i]+j);
77         }
78         if(check(g)) {puts("0");continue;}
79         for(ans = 1; ans < 6; ans++)
80             if(dfs(g,0)) break;
81         printf("%d
",ans<6?ans:-1);
82     }
83     return 0;
84 }
View Code

优化了下,效果不明显啊!

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <climits>
 7 #include <vector>
 8 #include <queue>
 9 #include <cstdlib>
10 #include <string>
11 #include <set>
12 #define LL long long
13 #define INF 0x3f3f3f3f
14 using namespace std;
15 int g[4][4],ans;
16 bool check(int (*t)[4]){
17     int i,j;
18     bool flag = false;
19     for(i = 0; i < 4; i++){
20         for(j = 1; j < 4; j++)
21         if(t[j][i] != t[j-1][i]) {flag = true;break;}//检查每一列
22         if(flag) break;
23     }
24     if(!flag) return true;
25     for(i = 0; i < 4; i++){
26         for(j = 1; j < 4; j++)
27         if(t[i][j] != t[i][j-1]) {flag = false;break;}
28         if(!flag) break;
29     }
30     return flag;
31 }
32 void shift(int (*t)[4],int dir,int u){
33     int i,temp;
34     if(dir == 0){//行左移
35         temp = t[u][0];
36         for(i = 0; i < 3; i++)
37             t[u][i] = t[u][i+1];
38         t[u][i] = temp;
39     }else if(dir == 3){//行右移
40         temp = t[u][3];
41         for(i = 3; i; i--)
42             t[u][i] = t[u][i-1];
43         t[u][i] = temp;
44     }else if(dir == 1){//列上移
45         temp = t[0][u];
46         for(i = 0; i < 3; i++)
47             t[i][u] = t[i+1][u];
48         t[i][u] = temp;
49     }else if(dir == 2){//列下移
50         temp = t[3][u];
51         for(i = 3; i; i--)
52             t[i][u] = t[i-1][u];
53         t[i][u] = temp;
54     }
55 }
56 
57 bool dfs(int (*t)[4],int step,int pre,int dir){
58     int mp[4][4],i,j,k;
59     if(ans == step && check(t)) return true;
60     if(ans <= step) return false;
61     for(i = 0; i < 4; i++){
62         for(j = 0; j < 4; j++){
63             memcpy(mp,t,sizeof(mp));
64             if(i == pre && j == dir) continue;
65             shift(mp,j,i);
66             if(dfs(mp,step+1,i,3-j)) return true;
67         }
68     }
69     return false;
70 }
71 int main(){
72     int ks,i,j;
73     scanf("%d",&ks);
74     while(ks--){
75         for(i = 0; i < 4; i++){
76             for(j = 0; j < 4; j++)
77                 scanf("%d",g[i]+j);
78         }
79         if(check(g)) {puts("0");continue;}
80         for(ans = 1; ans < 6; ans++)
81             if(dfs(g,0,-1,-1)) break;
82         printf("%d
",ans<6?ans:-1);
83     }
84     return 0;
85 }
View Code
原文地址:https://www.cnblogs.com/crackpotisback/p/3888076.html