POJ-3414

这个题···一开始写T了,后来想出来了判断重复的方法,然后就过了。

思路就是用1-6分别记录每个不同的操作,然后每个结构体里带个栈(写的时候我以为会爆内存)

然后用一个函数判断组合数是否重复出现就可以了,这个函数自己乱写的。

AC代码

#include<iostream>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring> 
#include<queue>
using namespace std;
#define ll long long
#define up(i,a,n) for(int i=a;i<=n;i++)
int a,b,c;
struct node
{
	int cnt;
	int A,B;
	vector<int>q;
}s;
bool vis[200000];
int f(int x,int y)
{
	return x*101+y*13+7;//瞎写的二元单调函数
}
node bfs(node aa)
{
	queue<node>q;
	q.push(aa);
	node sss;
	sss.cnt=-1;
	while(!q.empty())
	{
		node ss=q.front();q.pop();
		if(!vis[f(ss.A,ss.B)])continue;
		vis[f(ss.A,ss.B)]=false;
		if(ss.A==c||ss.B==c)return ss;
		ss.cnt++;
		if(ss.A!=0)//把1抽干 
		{
	    node ssa=ss;
	    ssa.A=0;
	    ssa.q.push_back(1);
		q.push(ssa);
	    }
	    if(ss.B!=0)//把2抽干 
	    {
		node ssa=ss;
		ssa.B=0;
		ssa.q.push_back(2);
		q.push(ssa);
	    }
	    if(ss.A!= a)//把1填满 
	    {
	    	node ssa=ss;
	    	ssa.A=a;
	    	ssa.q.push_back(3);
	    	q.push(ssa);
		}
		if(ss.B!=b)//把2填满 
		{
			node ssa=ss;
			ssa.B=b;
			ssa.q.push_back(4);
			q.push(ssa);
		}
	    if(ss.B+ss.A<=b) //把1倒入2 
	    {
	    	node ssa=ss;
	    	ssa.A=0;
	    	ssa.B=ss.A+ss.B;
	    	ssa.q.push_back(5);
	    	q.push(ssa);
		}
		if(ss.B+ss.A>b)//把1倒入2 
		{
		    node ssa=ss;
		    ssa.A=ss.A-(b-ss.B);
		    ssa.B=b;
		    ssa.q.push_back(5);
		    q.push(ssa);
		}
		if(ss.B+ss.A<=a)//把2倒入1 
		{
			node ssa=ss;
			ssa.A=ss.A+ss.B;
			ssa.B=0;
			//printf("%d %d\n",ss.A,ss.B);
			ssa.q.push_back(6);
			q.push(ssa);
		}
		if(ss.A+ss.B>a)//把2倒入1 
		{
			node ssa=ss;
			ssa.B=ss.B-(a-ss.A);
			ssa.A=a;
			//printf("%d %d\n",ssa.A,ssa.B);
			ssa.q.push_back(6);
			q.push(ssa);
		}
	}
	return sss;
}
void print()
{
	if(s.cnt==-1)printf("impossible\n");
	else
	{
		printf("%d\n",s.cnt);
		for(int i=0;i<s.q.size();i++)
		{
			switch(s.q[i])
			{
				case 1:printf("DROP(1)\n");break;
				case 2:printf("DROP(2)\n");break;
				case 3:printf("FILL(1)\n");break;
				case 4:printf("FILL(2)\n");break;
				case 5:printf("POUR(1,2)\n");break;
				case 6:printf("POUR(2,1)\n");break;
			}
		}
	}
}
int main()
{   memset(vis,true,sizeof(vis));
	scanf("%d %d %d",&a,&b,&c);
	s.A=0;
	s.B=0;
	s.cnt=0;
	s=bfs(s);
	print();
 } 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值