zoukankan      html  css  js  c++  java
  • hdu1495 && pku3414

    题意:

    大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子,它们的容量分别是N 毫升和M 毫升 可乐的体积为S (S<101)毫升 (正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0) 。聪明的ACMER你们说他们能平分吗?如果能请输出倒可乐的最少的次数,如果不能输出"NO"。
    分析:直接搜索+模拟
    对于N和M俩个杯子的当前状态,每次都有俩种选择,S->N,S->M,N->S,N->M,M->S,M->N
    用了BFS和DFS 个写了一个,写dfs的时候,开了个全局Debug了半天,ORZ
    BFS版
    #include<iostream>
    #include<algorithm>
    #include<queue>
    using namespace std;
    bool vis[110][110];
    short S,N,M,s,n,m;
    int ans;
    struct state
    {
    	short n,m;
    	short cnt;
    	state(short a=0,short b=0,short c=0):n(a),m(b),cnt(c){} 
    };
    queue<state> Q;
    void BFS()
    {
    	Q.push(state(0,0,0));
    	vis[0][0]=true;
    	state tmp;
    	while(!Q.empty())
    	{
    	    tmp=Q.front();
    		Q.pop();
    		if((tmp.n==S/2 || tmp.m==S/2)&&(S-(tmp.n+tmp.m))==S/2)
    		{
    			ans=tmp.cnt;
    			return ;
    		}
    	    s=S-tmp.n-tmp.m,n=tmp.n,m=tmp.m;
    		if(s!=0)
    		{
    			if(s+n>=N)
    			{
    				s-=(N-n);
    				n=N;
    			}
    			else {
    				n+=s;
    				s=0;
    			}
    			if(!vis[n][S-s-n]){
    				Q.push(state(n,S-s-n,tmp.cnt+1));
    				vis[n][S-s-n]=true;
    			}
    			s=S-tmp.n-tmp.m,n=tmp.n,m=tmp.m;
    			if(s+m>=M)
    			{
    				s-=(M-m);
    				m=M;
    			}
    			else m+=s,s=0;
    			if(!vis[S-s-m][m]){
    				Q.push(state(S-s-m,m,tmp.cnt+1));
    				vis[S-s-m][m]=true;
    			}
    		}
    		s=S-tmp.n-tmp.m,n=tmp.n,m=tmp.m;
    		if(n!=0)
    		{
    			if(!vis[0][m]){
    				Q.push(state(0,m,tmp.cnt+1));
    				vis[0][m]=true;
    			}
    			if(n+m>=M)
    			{
    				n-=(M-m);
    				m=M;
    			}
    			else m+=n,n=0;
    			if(!vis[n][m]){
    				Q.push(state(n,m,tmp.cnt+1));
    				vis[n][m]=true;
    			}
    		}
    		s=S-tmp.n-tmp.m,n=tmp.n,m=tmp.m;
    		if(m!=0)
    		{
    			if(!vis[n][0]){
    				Q.push(state(n,0,tmp.cnt+1));
    				vis[n][0]=true;
    			}
    			if(m+n>=N)
    			{
    				m-=(N-n);
    				n=N;
    			}
    			else n+=m,m=0;
    
    			if(!vis[n][m]){
    				Q.push(state(n,m,tmp.cnt+1));
    				vis[n][m]=true;
    			}
    		}
    	}
    }
    int main()
    {
    	while(scanf("%d %d %d",&S,&N,&M)==3 && (S||N||M))
    	{
    		if(S%2!=0)
    		{
    			puts("NO");
    			continue;
    		}
    		memset(vis,false ,sizeof(vis));
    		while(!Q.empty())
    			Q.pop();
    		ans=-1;
    		BFS();
    		if(ans==-1)
    			puts("NO");
    		else printf("%d\n",ans);
    	}
    }
    


    DFS版

    #include<iostream>
    const int inf=0x7fffffff;
    const int MAX=105;
    using namespace std;
    int ans;
    int S,N,M;
    bool vis[MAX][MAX];
    void dfs(int a,int b,int cnt)
    {
    //	cout<<"check"<<vis[0][3]<<endl;
    	if((a==S/2||b==S/2) && (S-(a+b))==S/2)
    	{
    	//	cout<<a<<' '<<b<<endl;
    		if(ans>cnt)
    			ans=cnt;
    		return ;
    	}
    	 int   s=S-a-b,n=a,m=b;
    		if(s!=0)
    		{
    			if(s+n>=N)
    			{
    				s-=(N-n);
    				n=N;
    			}
    			else n+=s,s=0;
    			if(!vis[n][m]){
    				vis[n][m]=1;
    		//		cout<<"S->n"<<endl;
    				dfs(n,m,cnt+1);
    				vis[n][m]=0;
    		//		cout<<"fan1 "<<n<<' '<<m<<' '<<vis[n][m]<<endl;
    			}
    			s=S-a-b,n=a,m=b;
    			if(s+m>=M)
    			{
    				s-=(M-m);
    				m=M;
    			}
    			else m+=s,s=0;
    		//	printf("%d    %d\n",n,m);
    		//	cout<<cnt<<endl;
    		//	cout<<vis[n][m]<<endl;
    			if(!vis[n][m]){
    				vis[n][m]=1;
    		//		cout<<"S->m"<<endl;
    				dfs(n,m,cnt+1);
    				vis[n][m]=0;
    		//		cout<<"fan2 "<<n<<' '<<m<<' '<<vis[n][m]<<endl;
    			}
    		}
    		s=S-a-b,n=a,m=b;
    		if(n!=0)
    		{
    			if(!vis[0][m]){
    				vis[0][m]=1;
    		//		cout<<"N->S"<<endl;
    				dfs(0,m,cnt+1);
    				vis[0][m]=0;
    		//		cout<<"fan3 "<<0<<' '<<m<<' '<<vis[0][m]<<endl;
    			}
    			if(n+m>=M)
    			{
    				n-=(M-m);
    				m=M;
    			}
    			else m+=n,n=0;
    			if(!vis[n][m]){
    				vis[n][m]=1;
    		//		cout<<"N->m"<<endl;
    				dfs(n,m,cnt+1);
    				vis[n][m]=0;
    		//		cout<<"fan4 "<<n<<' '<<m<<' '<<vis[n][m]<<endl;
    			}
    		}
    		s=S-a-b,n=a,m=b;
    		if(m!=0)
    		{
    			if(!vis[n][0]){
    				vis[n][0]=1;
    			//	cout<<"m->s"<<endl;
    				dfs(n,0,cnt+1);
    				vis[n][0]=0;
    			//	cout<<"fan5 "<<n<<' '<<m<<' '<<vis[n][0]<<endl;
    			}
    			if(m+n>=N)
    			{
    				m-=(N-n);
    				n=N;
    			}
    			else n+=m,m=0;
    			if(!vis[n][m]){
    				vis[n][m]=1;
    			//	cout<<"m->n"<<endl;
    				dfs(n,m,cnt+1);
    				vis[n][m]=0;
    			//	cout<<"fan6 "<<n<<' '<<m<<' '<<vis[n][m]<<endl;
    			}
    		}
    }
    int main(void)
    {
    	while(scanf("%d %d %d",&S,&N,&M)==3&& (S||N||M))
    	{
    		
    		if(S%2!=0)
    		{
    			puts("NO");
    			continue;
    		}
    		memset(vis,0,sizeof(vis));
    		ans=inf;
    		vis[0][0]=1;
    		dfs(0,0,0);
    		if(ans==inf)
    			puts("NO");
    		else printf("%d\n",ans);
    	}
    	return 0;
    }
    

     这是PKU上面一道类似的题目的代码,不同的是,这题目要求保存路径

    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<queue>
    using namespace std;
    struct state
    {
    	int a,b;
    	string road;
    	state(int x=0,int y=0,string str=""):a(x),b(y),road(str){}
    };
    //A : drop A
    //B : drop B
    //C : A to B
    //D : B to A
    //E : fill A
    //F " fill B
    queue<state> Q;
    int vis[101][101],A,B,C;
    bool success;
    string ans;
    void BFS()
    {
    	success=false;
    	Q.push(state(0,0,""));
    	memset(vis,false,sizeof(vis));
    	vis[0][0]=true;
    	while(!Q.empty())
    	{
    		state temp=Q.front();
    		string str=temp.road;
    		Q.pop();
    		int a=temp.a,b=temp.b,a1,b1;
    		if(a==C || b==C)
    		{
    			success=true;
    			ans=temp.road;
    			return ;
    		}
    		if(a!=0 && !vis[0][b])
    		{
    			vis[0][b]=true;
    			Q.push(state(0,b,(str + "A")));
    		}
    		if(b!=0 && !vis[a][0])
    		{
    			vis[a][0]=true;
    			Q.push(state(a,0,(str + "B")));
    		}
    		if(a!=0 && b!=B)
    		{
    			if(a+b<B)
    			{
    				b1=a+b;
    				a1=0;
    			}
    			else {
    				b1=B;
    				a1=a+b-B;
    			}
    			if(!vis[a1][b1])
    			{
    				vis[a1][b1]=true;
    				Q.push(state(a1,b1,(str+"C")));
    			}
    		}
    		if(a!=A && b!=0)
    		{
    			if(a+b<A)
    			{
    				a1=a+b;
    				b1=0;
    			}
    			else a1=A,b1=a+b-A;
    			if(!vis[a1][b1])
    			{
    				vis[a1][b1]=true;
    				Q.push(state(a1,b1,(str+"D")));
    			}
    		}
    		if(a!=A && !vis[A][b])
    		{
    			vis[A][b]=true;
    			Q.push(state(A,b,(str+"E")));
    		}
    		if(b!=B && !vis[a][B])
    		{
    			vis[a][B]=true;
    			Q.push(state(a,B,(str+"F")));
    		}
    	}
    }
    int main()
    {
    	while(scanf("%d %d %d",&A,&B,&C)==3)
    	{
    		while(!Q.empty())
    			Q.pop();
    		BFS();
    		if(!success)
    		{
    			puts("impossible");
    			continue;
    		}
    		//cout<<ans<<endl;
    		int len=ans.length();
    		printf("%d\n",len);
    		for(int i=0;i<len;i++)
    		{
    			if(ans[i]=='A')
    				puts("DROP(1)");
    			else if(ans[i]=='B')
    				puts("DROP(2)");
    			else if(ans[i]=='C')
    				puts("POUR(1,2)");
    			else if(ans[i]=='D')
    				puts("POUR(2,1)");
    			else if(ans[i]=='E')
    				puts("FILL(1)");
    			else puts("FILL(2)");
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    ORA-02020 : 过多的数据库链接在使用中-Windows环境解决步骤
    <转载>c++中new一个二维数组
    C C++输出格式 <转载>仅用于个人
    *p 和p[i] 区别
    Const *ptr ptr
    C 格式化的输入输出(printf scanf)
    PP 各种快捷键
    【Java并发工具类】原子类
    【Java并发工具类】Java并发容器
    【Java并发工具类】CountDownLatch和CyclicBarrier
  • 原文地址:https://www.cnblogs.com/nanke/p/2264312.html
Copyright © 2011-2022 走看看