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;
}