poj3414题解与思考 Pots
- 题意
- 知识点
- 题解:
首先第一次拿到这个题,觉得麻烦,想第一时间把答案中步数输出来,再去想怎么输出具体每一步怎么操作,于是就有了如下代码,(自己想的),用到bfs和队列)
#include<iostream>
#include<queue>
using namespace std;
struct set {
int a;
int b;
int step;
};
int amax, bmax, c;
bool vis[500][500];
void find() {
set x;
x.a = 0;
x.b = 0;
x.step = 0;
queue<set> q;
q.push(x);
vis[x.a][x.b] = true;
while (!q.empty()) {
set z;
set y = q.front();
q.pop();
if (y.a == c || y.b == c) {
cout << y.step << endl;
return;
}
for (int i = 0; i < 6; i++) {
//FILL(1)
if (i == 0) {
z.a = amax;
z.b = y.b;
if (!vis[z.a][z.b]) {
z.step = y.step + 1;
q.push(z);
vis[z.a][z.b] = true;
}
}
//FILL(2)
if (i == 1) {
z.a = y.a;
z.b = bmax;
if (!vis[z.a][z.b]) {
z.step = y.step + 1;
q.push(z);
vis[z.a][z.b] = true;
}
}
//DROP(1)
if (i == 2) {
z.a = 0;
z.b = y.b;
if (!vis[z.a][z.b]) {
z.step = y.step + 1;
q.push(z);
vis[z.a][z.b] = true;
}
}
//DROP(2)
if (i == 3) {
z.a = y.a;
z.b = 0;
if (!vis[z.a][z.b]) {
z.step = y.step + 1;
q.push(z);
vis[z.a][z.b] = true;
}
}
//POUR(1,2)
if (i == 4) {
if (y.a + y.b <= bmax) {
z.a = 0;
z.b = y.a + y.b;
if (!vis[z.a][z.b]) {
z.step = y.step + 1;
q.push(z);
vis[z.a][z.b] = true;
}
}
else if (y.a + y.b > bmax) {
z.a = (y.a + y.b) - bmax;
z.b = bmax;
if (!vis[z.a][z.b]) {
z.step = y.step + 1;
q.push(z);
vis[z.a][z.b] = true;
}
}
}
//POUR(2,1)
if (i == 5) {
if (y.a + y.b <= amax) {
z.a = y.a + y.b;
z.b =0;
if (!vis[z.a][z.b]) {
z.step = y.step + 1;
q.push(z);
vis[z.a][z.b] = true;
}
}
else if (y.a + y.b > amax) {
z.a = amax;
z.b = (y.a + y.b) - amax;
if (!vis[z.a][z.b]) {
z.step = y.step + 1;
q.push(z);
vis[z.a][z.b] = true;
}
}
}
}
}
}
int main() {
while (cin >> amax >> bmax >> c) {
memset(vis, false, sizeof(vis));
find();
}
return 0;
}
再进一步想想怎么输出每一步呐,用bfs搜索的,最后输出需要回溯,而bfs的回溯实现我暂时没有好的思路。苦思冥想,终于我想到了一个可实现的方法。
首先我们能想到,可以把for循环里的具体操作添加给结构体,添加一个string s
即可(因为for循环里的操作是有具体数字对应的,例如FULL(1)对应i=0)
其次我们观察到find函数里有z.step = y.step + 1
这就说明,其实每一步的操作是与前一步有联系的,如果我们能将之前的操作与当前的操作一同赋给结构体z,最后输出z.s时就输出了得到z的操作和之前的所有操作!
最后,由于“for循环里的操作是有具体数字对应的”我们完全可以只将数字添加给结构体,最后输出时根据数字输出对应的操作就好了!(用到switch语句)
代码奉上:
//AC! 相信自己,尊重题意!
#include<iostream>
#include<queue>
#include<string>
#include<cstring>
using namespace std;
struct set {
int a;
int b;
int step;
string s;
};
int amax, bmax, c;
bool vis[500][500];
void find() {
set x;
x.a = 0;
x.b = 0;
x.step = 0;
int head, tail;
//x.pos = head;
head = 0;
tail = 1;
queue<set> q;
//set queue[1000];
//queue[head] = x;
q.push(x);
vis[x.a][x.b] = true;
while (!q.empty()) {
set z;
set y = q.front();
if (y.a == c || y.b == c) {
cout << y.step << endl;
for (int i = 0; i < y.s.length(); i++) {
switch (y.s[i]) {
case '1':
cout << "FILL(1)" << endl;
break;
case '2':
cout << "FILL(2)" << endl;
break;
case '3':
cout << "DROP(1)" << endl;
break;
case '4':
cout << "DROP(2)" << endl;
break;
case '5':
cout << "POUR(1,2)" << endl;
break;
case '6':
cout << "POUR(2,1)" << endl;
break;
}
}
return;
}
for (int i = 0; i < 6; i++) {
//FILL(1)
if (i == 0) {
z.a = amax;
z.b = y.b;
if (!vis[z.a][z.b]) {
z.step = y.step + 1;
z.s = y.s + '1';
q.push(z);
vis[z.a][z.b] = true;
}
}
//FILL(2)
if (i == 1) {
z.a = y.a;
z.b = bmax;
if (!vis[z.a][z.b]) {
z.step = y.step + 1;
z.s = y.s + '2';
q.push(z);
vis[z.a][z.b] = true;
}
}
//DROP(1)
if (i == 2) {
z.a = 0;
z.b = y.b;
if (!vis[z.a][z.b]) {
z.step = y.step + 1;
z.s = y.s + '3';
q.push(z);
vis[z.a][z.b] = true;
}
}
//DROP(2)
if (i == 3) {
z.a = y.a;
z.b = 0;
if (!vis[z.a][z.b]) {
z.step = y.step + 1;
z.s = y.s + '4';
q.push(z);
vis[z.a][z.b] = true;
}
}
//POUR(1,2)
if (i == 4) {
if (y.a + y.b <= bmax) {
z.a = 0;
z.b = y.a + y.b;
if (!vis[z.a][z.b]) {
z.step = y.step + 1;
z.s = y.s + '5';
q.push(z);
vis[z.a][z.b] = true;
}
}
else if (y.a + y.b > bmax) {
z.a = (y.a + y.b) - bmax;
z.b = bmax;
if (!vis[z.a][z.b]) {
z.step = y.step + 1;
z.s = y.s + '5';
q.push(z);
vis[z.a][z.b] = true;
}
}
}
//POUR(2,1)
if (i == 5) {
if (y.a + y.b <= amax) {
z.a = y.a + y.b;
z.b =0;
if (!vis[z.a][z.b]) {
z.step = y.step + 1;
z.s = y.s + '6';
q.push(z);
vis[z.a][z.b] = true;
}
}
else if (y.a + y.b > amax) {
z.a = amax;
z.b = (y.a + y.b) - amax;
if (!vis[z.a][z.b]) {
z.step = y.step + 1;
z.s = y.s + '6';
q.push(z);
vis[z.a][z.b] = true;
}
}
}
}
q.pop();
}
cout << "impossible" << endl;
}
int main() {
while (cin >> amax >> bmax >> c) {
memset(vis, false, sizeof(vis));
find();
}
return 0;
}