本题传送门

本题知识点:宽度优先搜素 + 字符串

题意很简单,如何把用两个杯子,装够到第三个杯子的水。

操作有六种,这样就可以当作是bfs的搜索方向了

// FILL(1) 把第一个杯子装满
// FILL(2) 把第二个杯子装满
// POUR(1,2) 把第一个杯子的水倒进第二个杯子
// POUR(2,1) 把第二个杯子的水倒进第一个杯子
// DROP(1) 把第一个杯子的水都倒掉
// DROP(2) 把第二个杯子的水都倒掉

本题的难点是如何记录路径,我们可以用一个巧妙的方法去解决掉,详细请看代码

// POJ 3414
#include<iostream>
#include<cstdio>
#include<string>
#include<queue>
using namespace std; bool take[102][102], ok;
int A, B, C;
struct node{
string str;
int l, r, pla[102], cnt; // cnt 记录有多少条路径
};
queue<node> que;
string str[] = {
"FILL(1)",
"FILL(2)",
"POUR(1,2)",
"POUR(2,1)",
"DROP(1)",
"DROP(2)"
}; void show(int len, int pla[]){
printf("%d\n", len);
for(int i = 1; i <= len; i++){
cout << str[pla[i]] << endl;
}
} void bfs(){
ok = false;
take[0][0] = true;
node a;
a.str = "NONE";
a.l = a.r = a.cnt = 0;
que.push(a); while(!que.empty()){
node next, now = que.front(); que.pop(); // cout << now.str << " ";
// printf("l:%d r:%d cnt:%d\n", now.l, now.r, now.cnt);
// show(now.cnt, now.pla);
// cout << endl; if(now.l == C || now.r == C){
show(now.cnt, now.pla);
ok = true;
break;
} // FILL(1)
if(now.l < A && !take[A][now.r]){
next.str = str[0];
next.l = A;
next.r = now.r;
// 这句循环是为了保存之前的路径 下同
for(int i = 1; i <= now.cnt; i++){
next.pla[i] = now.pla[i];
}
next.pla[now.cnt + 1] = 0;
next.cnt = now.cnt + 1;
take[A][now.r] = true;
que.push(next);
} // FILL(2)
if(now.r < B && !take[now.l][B]){
next.str = str[1];
next.l = now.l;
next.r = B;
for(int i = 1; i <= now.cnt; i++){
next.pla[i] = now.pla[i];
}
next.pla[now.cnt + 1] = 1;
next.cnt = now.cnt + 1;
take[now.l][B] = true;
que.push(next);
} // POUR(1, 2)
if(0 < now.l && now.r < B){
int R = now.l + now.r >= B ? B : now.l + now.r;
int L = R - now.r >= now.l ? 0 : now.l - (R - now.r);
if(!take[L][R]){
next.str = str[2];
next.l = L;
next.r = R;
for(int i = 1; i <= now.cnt; i++){
next.pla[i] = now.pla[i];
}
next.pla[now.cnt + 1] = 2;
next.cnt = now.cnt + 1;
take[L][R] = true;
que.push(next);
}
} // POUR(2,1)
if(now.l < A && 0 < now.r){
int L = now.l + now.r >= A ? A : now.l + now.r;
int R = L - now.l >= now.r ? 0 : now.r - (L - now.l);
if(!take[L][R]){
next.str = str[3];
next.l = L;
next.r = R;
for(int i = 1; i <= now.cnt; i++){
next.pla[i] = now.pla[i];
}
next.pla[now.cnt + 1] = 3;
next.cnt = now.cnt + 1;
take[L][R] = true;
que.push(next);
}
} // DROP(1)
if(!take[0][now.r]){
next.str = str[4];
next.l = 0;
next.r = now.r;
for(int i = 1; i <= now.cnt; i++){
next.pla[i] = now.pla[i];
}
next.cnt = now.cnt + 1;
next.pla[now.cnt + 1] = 4;
take[0][now.r] = true;
que.push(next);
} // DROP(2)
if(!take[now.l][0]){
next.str = str[5];
next.l = now.l;
next.r = 0;
for(int i = 1; i <= now.cnt; i++){
next.pla[i] = now.pla[i];
}
next.cnt = now.cnt + 1;
next.pla[now.cnt + 1] = 5;
take[now.l][0] = true;
que.push(next);
} } if(!ok) printf("impossible\n");
} int main()
{
scanf("%d %d %d", &A, &B, &C); bfs(); return 0;
}

最新文章

  1. 关于SQL Server将一列的多行内容拼接成一行的问题讨论
  2. iOS开发中对RunLoop的个人心得
  3. thinkPHP学习笔记(2)
  4. iOS 时间戳
  5. 数据结构 《6》----堆 ( Heap )
  6. 创建可执行的JAR包
  7. ActiveMQ之JMSReplyTo
  8. Multi-Device Hybrid Apps (Preview)
  9. css如何li中选中后加上class属性js控制
  10. [置顶] Android4.0中修改挂断键(ENDCALL)的默认行为
  11. Java笔试题1
  12. Java设计模式菜鸟系列(十四)代理模式建模与实现
  13. cocos2d-x使用CCClippingNode实现跑马灯
  14. CISCO路由器练习
  15. signalR 消息推送
  16. Ceph集群搭建及Kubernetes上实现动态存储(StorageClass)
  17. C# [Win32] [GDI+] [API] Load HFONT from Memory
  18. Django学习手册 - 创建Django工程项目以及APP
  19. ES6_函数方法
  20. python基础学习笔记(一)

热门文章

  1. 推荐算法之E&amp;E
  2. Jmeter websocket插件安装与使用
  3. python自动备份阿里云数据库binlog
  4. 换个语言学一下 Golang (11)——使用包和测试
  5. 爬虫--selenium之 chromedriver与chrome版本映射表(最新至v2.46版本chromedriver)
  6. React组件中对子组件children进行加强
  7. android Camera 之 ZSL
  8. SAP CDS重定向视图和直接读这两者场景的性能比较
  9. kubernetes网络之Flannel
  10. H3C STA&gt;PC的数据转发