标签:
此题为小白书暴力求解法隐式图搜索的训练参考
题目链接 http://acm.hust.edu.cn/vjudge/problem/19527
解题思路
因为要求最小倒水量,所以不能把重复的节点都去掉,要把倒水量比较小的节点也加进去。
可以建立一个water数组,water[x]表示达到x水量的最小倒水量。之后每次扩展节点或者
是加入较小节点,也要更新water数组。
要具体的话可以看代码。
代码
#include<stdio.h> #include<string.h> const int maxLen = 5e5; typedef struct node { int cup[3]; int water; }Node; Node Q[maxLen]; int waters[201]; bool ex[201][201][201]; int maxcup[3]; int target; bool match(Node x) { return ex[x.cup[0]][x.cup[1]][x.cup[2]]; } bool Judge(Node x) { if(x.water<waters[x.cup[0]]) { waters[x.cup[0]]=x.water;return true; } if(x.water<waters[x.cup[1]]) { waters[x.cup[1]]=x.water;return true; } if(x.water<waters[x.cup[2]]) { waters[x.cup[2]]=x.water;return true; } return false; } int Search(Node Start) { bool yes=false; int front=-1, rear=-1; Q[++rear] = Start; ex[Start.cup[0]][Start.cup[1]][Start.cup[2]]=true; Judge(Start); while(front != rear) { Node temp = Q[++front]; for(int i=0; i<3; i++) for(int j=0; j<3; j++) if(i!=j) { Node mid = temp; mid.cup[i]+=temp.cup[j]+temp.cup[i]<=maxcup[i]?temp.cup[j]:maxcup[i]-temp.cup[i]; mid.cup[j]=temp.cup[j]+temp.cup[i]<=maxcup[i]?0:temp.cup[j]-maxcup[i]+temp.cup[i]; mid.water+=temp.cup[j]+temp.cup[i]<=maxcup[i]?temp.cup[j]:maxcup[i]-temp.cup[i]; if(!match(mid) || Judge(mid)) { Q[++rear] = mid; ex[mid.cup[0]][mid.cup[1]][mid.cup[2]]=true; } } } while(target>=0) { if(waters[target]!=1e9) return waters[target]; target--; } } int main() { int n; scanf("%d", &n); while(n--) { memset(ex, 0, sizeof(ex)); for(int i=0; i<201; i++) waters[i]=1e9; scanf("%d%d%d%d", &maxcup[0], &maxcup[1], &maxcup[2], &target); if(target>200) target=200; Node start; start.cup[2] = maxcup[2]; start.cup[0] = start.cup[1] = 0; start.water = 0; int water = Search(start); printf("%d %d\n", water, target); } return 0; }
标签:
原文地址:http://www.cnblogs.com/ZengWangli/p/5768668.html