您的位置:首页 > 编程语言 > C语言/C++

HDU 1495非常可乐(BFS)

2014-05-06 23:33 507 查看
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1495

话说从这个题中我发现了一个惊天的秘密!我以前写的BFS好多都写多余了!!sad。。

因为这题需要标记数组,我以前一直都是传递数组,但这道题的标记数组需要10^6的数组大小,光传递的时候就需要10^6的复杂度。。于是想了好长时间怎样把标记数组写的小一点,因为和是一定的,所以可以把因数变小。开始想到s*4+n*2+m的结果标记,结果提交WA,然后发现(1,0,2)与(0,3,0)是一样的。。。然后又改成s*3+n*2+m,虽然没想出反例,但还是WA。。然后无奈找了找题解(再次表示罪过罪过。。),发现不用传递。。我仔细想了想。。的确不用传递。。。。。。而且不传递还能节省好大一部分无用的时间。。sad。。以前的有好多BFS的题都写挫了。。

这题很有收获。。发现的这个问题很严重啊。。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <queue>
#include <map>
#include<algorithm>

using namespace std;
int s, n, m, vis[101][101][101];
struct node
{
int a, b, c, ans;
};
void bfs()
{
int i, j, x;
queue<node>q;
node f1, f2;
memset(vis,0,sizeof(vis));
f1.a=s;
f1.b=0;
f1.c=0;
f1.ans=0;
q.push(f1);
vis[s][0][0]=1;
while(!q.empty())
{
f1=q.front();
//printf("%d %d %d %d\n",f1.a,f1.b,f1.c,f1.ans);
q.pop();
if((f1.a==s/2)+(f1.b==s/2)+(f1.c==s/2)==2)
{
printf("%d\n",f1.ans);
return ;
}
if(f1.b<n)
{
x=f1.a+f1.b;
if(x>=n)
{
f2.b=n;
f2.a=x-n;
}
else
{
f2.b=x;
f2.a=0;
}
f2.c=f1.c;
f2.ans=f1.ans+1;
if(!vis[f2.a][f2.b][f2.c])
{
vis[f2.a][f2.b][f2.c]=1;
q.push(f2);
}
f2.a=f1.a;
x=f1.c+f1.b;
if(x>=n)
{
f2.b=n;
f2.c=x-n;
}
else
{
f2.b=x;
f2.c=0;
}
if(!vis[f2.a][f2.b][f2.c])
{
vis[f2.a][f2.b][f2.c]=1;
q.push(f2);
}
}
if(f1.a<s)
{
x=f1.a+f1.b;
if(x>=s)
{
f2.a=s;
f2.b=x-s;
}
else
{
f2.a=x;
f2.b=0;
}
f2.c=f1.c;
f2.ans=f1.ans+1;
if(!vis[f2.a][f2.b][f2.c])
{
vis[f2.a][f2.b][f2.c]=1;
q.push(f2);
}
x=f1.a+f1.c;
if(x>=s)
{
f2.a=s;
f2.c=x-s;
}
else
{
f2.a=x;
f2.c=0;
}
f2.b=f1.b;
if(!vis[f2.a][f2.b][f2.c])
{
vis[f2.a][f2.b][f2.c]=1;
q.push(f2);
}
}
if(f1.c<m)
{
x=f1.c+f1.b;
if(x>=m)
{
f2.c=m;
f2.b=x-m;
}
else
{
f2.c=x;
f2.b=0;
}
f2.a=f1.a;
f2.ans=f1.ans+1;
if(!vis[f2.a][f2.b][f2.c])
{
vis[f2.a][f2.b][f2.c]=1;
q.push(f2);
}
x=f1.a+f1.c;
if(x>=m)
{
f2.c=m;
f2.a=x-m;
}
else
{
f2.c=x;
f2.a=0;
}
f2.b=f1.b;
if(!vis[f2.a][f2.b][f2.c])
{
vis[f2.a][f2.b][f2.c]=1;
q.push(f2);
}
}
}
printf("NO\n");
}
int main()
{
while(scanf("%d%d%d",&s,&n,&m)!=EOF&&s&&n&&m)
{
if(s%2)
printf("NO\n");
else
bfs();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言 算法 编程 bfs