FOJ Problem 1081 等分液体
2016-03-15 14:36
232 查看
Problem Description
有三种容器R1,R2,R3,其容积分别是L,M,N。L,M,N 都是正整数且L=M+N。今R1 装满液体,试用最少的操作步骤 将 R1 中的液体均分。
Input
第一行仅包含一个表示测试例个数的正整数n 。以下n 行为 n个测试例的输入数据。每个测试例仅有一行输入数据,含三个正整数L,M,N (1<=L,M,N<=150),两数间用一个空格隔开。
Output
每个测试例都仅有一行输出,若有解,输出操作的次数,若无解则输出“no”。
Sample Input
3
100 70 30
90 60 30
80 45 35
Sample Output
9
no
15
这一题我当做搜索题来做,既然说是最少,当然第一想到优先队列是不是,然后每一次从最少步数的那一个节点开始继续往后搜索
有三种容器R1,R2,R3,其容积分别是L,M,N。L,M,N 都是正整数且L=M+N。今R1 装满液体,试用最少的操作步骤 将 R1 中的液体均分。
Input
第一行仅包含一个表示测试例个数的正整数n 。以下n 行为 n个测试例的输入数据。每个测试例仅有一行输入数据,含三个正整数L,M,N (1<=L,M,N<=150),两数间用一个空格隔开。
Output
每个测试例都仅有一行输出,若有解,输出操作的次数,若无解则输出“no”。
Sample Input
3
100 70 30
90 60 30
80 45 35
Sample Output
9
no
15
这一题我当做搜索题来做,既然说是最少,当然第一想到优先队列是不是,然后每一次从最少步数的那一个节点开始继续往后搜索
# include <iostream> # include <string.h> # include <queue> # include <algorithm> using namespace std; struct state{//每一个状态 int v[4];//三个杯子,下标从一开始 int cnt;//当前步数 bool operator <(const state& rhs) const{ return cnt>rhs.cnt; } }; priority_queue<state> q;//优先队列 int vis[160][160];//记录是否被访问过 int main(){ int t, i, j, k, d; int cup[4];//三个杯子容量 cin>>t; for(i=1; i<=t; i++){ cin>>cup[1]>>cup[2]>>cup[3]; if(cup[1]%2==1){//奇数没有办法均分 printf("no\n"); continue; } memset(vis, 0, sizeof(vis)); while(!q.empty()){ q.pop(); } d=cup[1]/2;//目标 struct state start;//开始状态 start.v[1]=cup[1]; start.v[2]=0; start.v[3]=0; start.cnt=0; vis[start.v[1]][start.v[2]]=vis[start.v[2]][start.v[1]]=1;//第一个状态标记为已经出现 q.push(start); int flage=0; while(!q.empty()){ struct state temp=q.top(); q.pop(); if(temp.v[1]==d||temp.v[2]==d||temp.v[3]==d){//到达目标 printf("%d\n", temp.cnt+1); flage=1; break; } for(j=1; j<=3; j++){//从第j个杯子倒到第k个 for(k=1; k<=3; k++){ if(j!=k){ if(temp.v[j]==0||temp.v[k]==cup[k]){//操作失败继续下一种策略 continue; } else{ struct state _temp; memcpy(&_temp, &temp, sizeof(temp));//备份一下,不能破坏temp int amount=min(cup[k], temp.v[j]+temp.v[k])-temp.v[k];//计算到水量 _temp.v[j]=temp.v[j]-amount;//更新 _temp.v[k]=temp.v[k]+amount;//更新 _temp.cnt++;//更新 if(vis[_temp.v[j]][_temp.v[k]]==0&&vis[_temp.v[k]][_temp.v[j]]==0){//找到新状态,入队 q.push(_temp); vis[_temp.v[j]][_temp.v[k]]=vis[_temp.v[k]][_temp.v[j]]=1; } } } } } } if(!flage){//没找到 printf("no\n"); } } return 0; }
相关文章推荐
- 让软件支持Retina
- JavaScript高级程序设计学习笔记--事件(二)(事件对象--DOM中的事件对象/IE中的事件对象/跨浏览器的事件对象)
- APPIUM测试Inspecter connection error问题
- Java集合类
- list、set、map、array间的相互转换
- (五)boost库之随机数random
- 精度因子PDOP TDOP HDOP VDOP
- iOS : performSelectorOnMainThread
- C语言中压缩字符串的简单算法小结
- Hadoop MapReduceV2(Yarn) 框架简介
- (四)boost库之正则表达式regex
- POJ 1375 圆切线
- Enable Auto Deploy on vCenter Server Appliance (vCSA) 6
- 背包问题求解
- 一般背包问题
- python 列表推导式
- Android5.0新特性——兼容性(support)
- Android:带输入框的弹窗
- 类
- Servlet与Jsp的区别