hdu 1195 Open the Lock
http://acm.hdu.edu.cn/showproblem.php?pid=1195
这个题广搜,不过我开始写的超内存了,估计是广搜队列太长了。
然后借鉴了别人的代码来AC。。但是有一点没想通,不就是循环范围改了一下,为什么内存差别这么大。无语。。
一开始超内存代码:
#include<iostream> #include<cstdio> #include<queue> #include<cstring> using namespace std; struct Node { int nu[4]; //记录四个位置的密码值 int sum; }p; int lock[10][10][10][10]; //判重记录 int pas[4]; //记录最后的密码 int a,b,c,d; void Bfs() { queue<Node> q; Node now,next; int i; int exchange; q.push(p); while(!q.empty()) { now = q.front(); q.pop(); for(i = 0; i < 4; i++) //判断密码是否正确 { if(now.nu[i] != pas[i]) { break; } } if(i == 4) { printf("%d\n",now.sum); break; } for(i = 0; i < 4; i++) //每个循环只操作一次 { next = now; next.sum++; next.nu[i] = now.nu[i]+1; //第i个数增加一 if(next.nu[i] > 9) { next.nu[i] = 1; } if(lock[next.nu[0]][next.nu[1]][next.nu[2]][next.nu[3]] == 0) //如果没有经过则入队 { lock[next.nu[0]][next.nu[1]][next.nu[2]][next.nu[3]] = 1; q.push(next); } next.nu[i] = now.nu[i]-1; //减少一 if(next.nu[i] < 1) { next.nu[i] = 9; } if(lock[next.nu[0]][next.nu[1]][next.nu[2]][next.nu[3]] == 0) { lock[next.nu[0]][next.nu[1]][next.nu[2]][next.nu[3]] = 1; q.push(next); } if(i<3) //两个数交换 { next = now; nex.sum++; exchange = next.nu[i]; next.nu[i] = next.nu[i+1]; next.nu[i+1] = exchange; q.push(next); } } } } int main() { int t,x; scanf("%d",&t); while(t--) { memset(lock,0,sizeof(lock)); memset(pas,0,sizeof(pas)); scanf("%d",&x); //输入当前密码值 p.nu[3] = a = x%10; x = x/10; p.nu[2] = b = x%10; x = x/10; p.nu[1] = c = x%10; x = x/10; p.nu[0] = d = x; lock[d][c][b][a] = 1; p.sum = 0; scanf("%d",&x); //输入最终密码 pas[3] = x%10; x = x/10; pas[2] = x%10; x = x/10; pas[1] = x%10; x = x/10; pas[0] = x; Bfs(); } return 0; }
AC代码:
#include<iostream> #include<cstdio> #include<queue> #include<cstring> using namespace std; struct Node { int nu[4]; //记录四个位置的密码值 int sum; }p; int lock[10][10][10][10]; //判重记录 int pas[4]; //记录最后的密码 int a,b,c,d; void Bfs() { queue<Node> q; Node now,next; int i; q.push(p); while(!q.empty()) { now = q.front(); q.pop(); for(i = 0; i < 4; i++) //判断密码是否正确 { if(now.nu[i]!=pas[i]) { break; } } if(i==4) { printf("%d\n",now.sum); break; } for(i = 0; i < 4; i++) //每位加一操作 { next = now; next.nu[i] = now.nu[i]+1; if(next.nu[i]>9) { next.nu[i] = 1; } if(lock[next.nu[0]][next.nu[1]][next.nu[2]][next.nu[3]]!=1) { lock[next.nu[0]][next.nu[1]][next.nu[2]][next.nu[3]]=1; //标记 next.sum = now.sum+1; q.push(next); } } for(i = 0; i < 4; i++) //每位减一操作 { next = now; next.nu[i] = now.nu[i]-1; if(next.nu[i]<1) { next.nu[i] = 9; } if(lock[next.nu[0]][next.nu[1]][next.nu[2]][next.nu[3]]!=1) { lock[next.nu[0]][next.nu[1]][next.nu[2]][next.nu[3]]=1; next.sum = now.sum+1; q.push(next); } } for(i = 0; i < 3; i++) //相邻的交换 { next = now; next.nu[i] = now.nu[i+1]; next.nu[i+1] = now.nu[i]; if(lock[next.nu[0]][next.nu[1]][next.nu[2]][next.nu[3]]!=1) { lock[next.nu[0]][next.nu[1]][next.nu[2]][next.nu[3]]=1; next.sum = now.sum+1; q.push(next); } } } } int main() { int t,x; scanf("%d",&t); while(t--) { memset(lock,0,sizeof(lock)); memset(pas,0,sizeof(pas)); scanf("%d",&x); //输入当前密码值 p.nu[3] = a = x%10; x = x/10; p.nu[2] = b = x%10; x = x/10; p.nu[1] = c = x%10; x = x/10; p.nu[0] = d = x; lock[d][c][b][a] = 1; p.sum = 0; scanf("%d",&x); //输入最终密码 pas[3] = x%10; x = x/10; pas[2] = x%10; x = x/10; pas[1] = x%10; x = x/10; pas[0] = x; Bfs(); } return 0; }