母亲的牛奶(cow.cpp)
【题目描述】
农民约翰有三个容量分别是A,B,C升的桶,A、B、C分别是三个从1到20的整数。
最初,A和B桶都是空的,而C桶是装满牛奶的。
有时,约翰把牛奶从一个桶倒到另一个桶中,直到被灌桶装满或原桶空了。由于节约,牛奶不会有丢失。
写一个程序去帮助约翰找出当A桶是空的时候,C桶中牛奶所剩量的所有可能性。
【输入】
第1行:3个整数A,B和C。
【输出】
第1行:升序地列出当A桶是空的时候,C桶牛奶所剩量的所有可能性。
【样例输入】
2 5 10
【样例输出】
5 6 7 8 9 10
这道题有些(其实是很)难把代码写短,一开始bfs用了178(不要惊讶,我没有多打一个8)行,呵呵~于是为了更精简,我把六个鬼祟的if语句改成了for双重循环if一次搞定,还把三维vis变成了二维,改变挺大的,但是……居然只有五分!!!然后我气愤的使用了随机数函数,疯狂和同学对答案(对拍,嗯,对拍),居然全对,可是交上去还是五分……还是把大部分数据都能过的代码公布,希望神犇们指出错误!代码如下:
#include
#include
#include
#include
using namespace std;
struct node
{
int x;
int y;
};
queueque;
int vis[25][25];
int M[3];
void bfs()
{
while(!que.empty())
{
for(int i=0;i<=2;i++)
{
for(int j=0;j<=2;j++)
{
int A[3]={que.front().x,que.front().y,M[2]-A[0]-A[1]};
if(i==j)
{
continue;
}
int s=A[i]+A[j];
A[j]=min(s,M[j]);
A[i]=s-A[j];
if(!vis[A[0]][A[1]])
{
vis[A[0]][A[1]]=1;
node n;
n.x=A[0];
n.y=A[1];
que.push(n);
}
}
}
que.pop();
}
}
int main()
{
//freopen("cow.in","r",stdin);
//freopen("cow.out","w",stdout);
//freopen("1.txt","r",stdin);
scanf("%d%d%d",&M[0],&M[1],&M[2]);
//for(M[0]=1;M[0]<=20;M[0]++)
//{
//for(M[1]=1;M[1]<=20;M[1]++)
//{
//for(M[2]=1;M[2]<=20;M[2]++)
//{
vis[0][0]=1;
node n;
n.x=0;
n.y=0;
que.push(n);
bfs();
int c=0;
//printf("%d %d %d:",M[0],M[1],M[2]);
for(int i=M[2];i>=0;i--)
{
if(vis[0][i]==1)
{
if(c==1)
{
printf(" ");
}
c=1;
printf("%d",M[2]-i);
}
}
memset(vis,0,sizeof(vis));
//printf("\n");
//}
//}
//}
}
终于发现了错误了!我在赋A[2]初值的时候,就用到了A[0]和A[1],结果有时候就会莫名其妙的炸了……然后这是我的AC代码:
#include
#include
#include
#include
using namespace std;
struct node
{
int x;
int y;
};//定义结构体
queueque;//队列
int vis[25][25];//标记数组
int M[3];//牛奶上限
void bfs()
{
while(!que.empty())//队列非空运行
{
for(int i=0;i<=2;i++)//枚举六个方向
{
for(int j=0;j<=2;j++)
{
int A[3]={que.front().x,que.front().y};//现在的牛奶数量
A[2]=M[2]-A[0]-A[1];
if(i==j)//相等则跳过
{
continue;
}
int s=A[i]+A[j];//s为两桶牛奶之和
A[j]=min(s,M[j]);//要么倒满,要么倒完,取小的一个
A[i]=s-A[j];//另外一个为和减去那一个
if(!vis[A[0]][A[1]])//如果没有标记过,则进入
{
vis[A[0]][A[1]]=1;//标记
node n;
n.x=A[0];
n.y=A[1];
que.push(n);//入队
}
}
}
que.pop();//出队
}
}
int main()
{
//freopen("cow.in","r",stdin);//freopen输入
//freopen("cow.out","w",stdout);//freopen输出
scanf("%d%d%d",&M[0],&M[1],&M[2]);//读入
vis[0][0]=1;//标记原始点
node n;
n.x=0;
n.y=0;
que.push(n);//入队
bfs();//广搜
int c=0;
for(int i=M[2];i>=0;i--)
{
if(vis[0][i]==1)//当B桶可以为i时,C桶便多了一种状态
{
if(c==1)
{
printf(" ");
}
c=1;
printf("%d",M[2]-i);//输出
}
}
}