HDU 1495 非常可乐 解题报告

9 篇文章 0 订阅
5 篇文章 0 订阅

非常可乐

思路

六大状态,一共12种子状态。
慢慢写呗,不要烦躁就写的对。

题解代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define N 100+5
using namespace std;
 
struct node{
    int a,b,s,t;
}cole[N],st;
 
int a,b,s;
int vis[N][N];  //记录状态(二维就可以记录三维的状态)。
queue<node> q;
void init(){
	memset(vis,0,sizeof(vis));
	while ( q.empty() == 0 )	q.pop();
}
void bfs()
{
    
    memset(vis,0,sizeof(vis));
    st.a=0; st.b=0; st.s=s; st.t=0;
    q.push(st);
    vis[0][0]=1;
    while(!q.empty())
    {
        node u=q.front(),v;        
		q.pop();
        //能平分的条件是可乐瓶和容量大(a)的杯子都装着最开始一半的可乐。
        if(u.a==s/2 && u.s==s/2){
        	printf("%d\n",u.t);
			return ; 
        }

		if ( u.s && u.a != a){
			int c = a - u.a; 
			if ( u.s >= c )	v.a = a 	, v.s = u.s - c; 
			else 			v.a = u.a+u.s,v.s = 0; 
			v.b = u.b; v.t = u.t + 1; 
			if ( vis[v.a][v.b] == 0){
				vis[v.a][v.b] = 1; 
				q.push(v);
			}
		}
//		s -> b; 	
		if ( u.s && u.b != b){
			int c = b - u.b; 
			if ( u.s >= c )	v.b = b 	, v.s = u.s - c; 
			else 			v.b = u.b+u.s,v.s = 0; 
			v.a = u.a; v.t = u.t + 1; 
			if ( vis[v.a][v.b] == 0){
				vis[v.a][v.b] = 1; 
				q.push(v);
			}
		}	
//		a -> s; 			
		if ( u.a && u.s != s){
			int c = s - u.s; 
			if ( u.a >= c )	v.s = s 	, v.a = u.a - c; 
			else 			v.s = u.s+u.a,v.a = 0; 
			v.b = u.b; v.t = u.t + 1; 
			if ( vis[v.a][v.b] == 0){
				vis[v.a][v.b] = 1; 
				q.push(v);
			}
		}		
//		a -> b; 
		if ( u.a && u.b != b){
			int c = b - u.b; 
			if ( u.a >= c )	v.b = b 	, v.a = u.a - c; 
			else 			v.b = u.b+u.a,v.a = 0; 
			v.s = u.s; v.t = u.t + 1; 
			if ( vis[v.a][v.b] == 0){
				vis[v.a][v.b] = 1; 
				q.push(v);
			}
		}			
//		b -> s; 
		if ( u.b && u.s != s){
			int c = s - u.s; 
			if ( u.b >= c )	v.s = s 	, v.b = u.b - c; 
			else 			v.s = u.s+u.b,v.b = 0; 
			v.a = u.a; v.t = u.t + 1; 
			if ( vis[v.a][v.b] == 0){
				vis[v.a][v.b] = 1; 
				q.push(v);
			}
		}
//		b -> a; 
		if ( u.b && u.a != a){
			int c = a - u.a; 
			if ( u.b >= c )	v.a = a 	, v.b = u.b - c; 
			else 			v.a = u.a+u.b,v.b = 0; 
			v.s = u.s; v.t = u.t + 1; 
			if ( vis[v.a][v.b] == 0){
				vis[v.a][v.b] = 1; 
				q.push(v);
			}
		}		

    }
    printf("NO\n");
//    return 0;   //所有扩展的状态都不能使之平分。
}
int main()
{
//	freopen("1.txt","r",stdin);	
    while(scanf("%d%d%d",&s,&a,&b),s||a||b)
    {
    	init();
        if(s%2)
        {
            puts("NO");
            continue;
        }
        if(a<b) swap(a,b); //这里使a作大号杯,方便bfs条件的判定。
        bfs();
//        if(ans) printf("%d\n",ans);
//        else puts("NO");
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值