NYOJ21 三个水杯
来源:互联网 发布:2017年网络剧 编辑:程序博客网 时间:2024/05/16 00:41
题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=21
题目分析:
暴力+BFS。将所有可能的状态压到队列中,直到找到目标状态为止。
我自己AC的代码。
#include<stdio.h>#include<string.h>//三个水杯的盛水的状态struct Node{int a;//水杯1的水量int b;//水杯2的水量int c;//水杯3的水量int flag;};Node queue[100];bool used[101][101][101];inline void Pour(Node p,int &tail){if(!used[p.a][p.b][p.c]){queue[++tail] = p;used[p.a][p.b][p.c] = true;}}inline int min(const int a, const int b){return a < b ? a :b;}//寻找倒水路径int PourWaterTwo(int *goal, int *vol){int head = 0;int tail = 0;int temp;Node s,p;while(head <= tail){s = queue[head];//将1倒入2或3中if(s.a > 0){if(s.b < vol[1]){temp = min(vol[1] - s.b , s.a);p.a = s.a - temp;p.b = s.b + temp;p.c = s.c;p.flag = s.flag + 1;if(p.a == goal[0] && p.b == goal[1] && p.c == goal[2])return p.flag;Pour(p,tail);}if(s.c < vol[2]){temp = min(vol[2] - s.c , s.a);p.a = s.a - temp;p.b = s.b;p.c = s.c + temp;p.flag = s.flag + 1;if(p.a == goal[0] && p.b == goal[1] && p.c == goal[2])return p.flag;Pour(p,tail);}}//将2倒入1或3中if(s.b > 0){if(s.a < vol[0]){temp = min(vol[0] - s.a , s.b);p.a = s.a + temp;p.b = s.b - temp;p.c = s.c;p.flag = s.flag + 1;if(p.a == goal[0] && p.b == goal[1] && p.c == goal[2])return p.flag;Pour(p,tail);}if(s.c < vol[2]){temp = min(vol[2] - s.c , s.b);p.a = s.a;p.b = s.b - temp;p.c = s.c + temp;p.flag = s.flag + 1;if(p.a == goal[0] && p.b == goal[1] && p.c == goal[2])return p.flag;Pour(p,tail);}}if(s.c > 0)//将3倒入1,2中{if(s.a < vol[0]){temp = min(vol[0] - s.a , s.c);p.a = s.a + temp;p.b = s.b;p.c = s.c - temp;p.flag = s.flag + 1;if(p.a == goal[0] && p.b == goal[1] && p.c == goal[2])return p.flag;Pour(p,tail);}if(s.b < vol[1]){temp = min(vol[1] - s.b , s.c);p.a = s.a;p.b = s.b + temp;p.c = s.c - temp;p.flag = s.flag + 1;if(p.a == goal[0] && p.b == goal[1] && p.c == goal[2])return p.flag;Pour(p,tail);}}++head;}return -1;}int main(){int goal[3];int vol[3];int t;scanf("%d", &t);queue[0].b = 0;queue[0].c = 0;queue[0].flag = 0;while(t--){memset(used,0,sizeof(used));scanf("%d %d %d", &vol[0], &vol[1], &vol[2]);scanf("%d %d %d",&goal[0], &goal[1], &goal[2]);queue[0].a = vol[0];used[vol[0]][0][0] = true;if(goal[0] + goal[1] + goal[2] != vol[0]){printf("-1\n");continue;}if(goal[0] == vol[0] && !goal[1] && !goal[2]){printf("0\n");continue;}printf("%d\n",PourWaterTwo(goal,vol));}}
OJ上的最优代码,当时我写的时候就在想怎么优化,其实想到了一点点,不过还是太弱了,最终没有搞出来。看看大牛的作品。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<bitset> using namespace std; #define CLR(arr,val) memset(arr,val,sizeof(arr)) bitset<1000000> Hash; const int MAX_STEP=100000; int WQ[MAX_STEP][4],Goal[3],Cap[3],goalval; int head=0,tail=0; void movw(int numfrom,int numto,int other) { int total=WQ[head][numfrom]+WQ[head][numto]; WQ[tail][other]=WQ[head][other]; WQ[tail][3]=WQ[head][3]+1; if(total>Cap[numto]) { WQ[tail][numfrom]=total-Cap[numto]; WQ[tail][numto]=Cap[numto]; } else { WQ[tail][numfrom]=0; WQ[tail][numto]=total; } int hashval=WQ[tail][0]*10000+WQ[tail][1]*100+WQ[tail][2]; if(hashval==goalval) throw WQ[head][3]+1; if(WQ[head][numfrom]!=0 && !Hash[hashval]) { Hash[hashval]=true; if(++tail==MAX_STEP) tail=0; } } int main() { int t; scanf("%d",&t); while(t--) { Hash.reset(); scanf("%d%d%d%d%d%d",&Cap[0],&Cap[1],&Cap[2],&Goal[0],&Goal[1],&Goal[2]); head=0,tail=0,goalval=Goal[0]*10000+Goal[1]*100+Goal[2]; if(Goal[1]==0 && Goal[2]==0 && Goal[0]==Cap[0]) {puts("0");continue;} WQ[tail][0]=Cap[0];WQ[tail][1]=0;WQ[tail][2]=0;WQ[tail][3]=0; ++tail; try{ while(head!=tail) { movw(0,1,2);movw(1,2,0);movw(0,2,1);movw(1,0,2);movw(2,1,0);movw(2,0,1); if(++head==MAX_STEP) head=0; } puts("-1"); }catch(int step) { printf("%d\n",step); } } }
- NYOJ21 三个水杯
- NYOJ21 三个水杯
- NYOJ21-三个水杯
- NYOJ21 三个水杯
- NYOJ21 三个水杯
- nyoj21 三个水杯倒水
- NYOJ21-三个水杯
- NYOJ21 三个水杯 【BFS】
- NYOJ21 【三个水杯】
- nyoj21三个水杯
- nyoj21三个水杯。。
- NYoj21-三个水杯-BFS
- NYoj21 三个水杯
- nyoj21三个水杯
- nyoj21三个水杯
- NYOJ21三个水杯
- nyoj21 三个水杯
- NYOJ21 三个水杯
- CentOS下安装php
- 复数的加法(友元函数)
- codeforce 67C - Sequence of Balls(dp)
- spring aop 同一个类中一个方法调用另一个方法,拦截不到被调用的方法
- 周鸿祎:微信已经从精神上把运营商干掉了
- NYOJ21 三个水杯
- linux学习笔记(一)—— vmwaretools实现ubuntu11.10虚拟机与win7主机文件共享
- mahout learning 代码示例
- 作者 刘韧 2013-4-10 19:24 评论(16) 巨人网络 史玉柱 大中小 虎嗅注:这是刘韧五年前对史玉柱的专访,回顾了史玉柱从童年到高校,从下海做汉卡到盖巨人大厦,再从惨败到脑白金的东
- hive基础
- Linux信号(signal) 机制分析
- PopUpAnchor control
- 程序员妻子自述:那些程序员教给我的
- [COM/ATL]COM组件编程——初步了解