Pots POJ - 3414

题目传送门

题意:就是倒水问题,给你连个杯子,一个杯子的容量是a,另一个杯子的容量是b,一共有六种操作问你最少几次能使其中的一个杯子的水是c,打印出来操作。

思路:BFS+记录路径

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define MAXN 110
#define MAXE 210
#define INF 10000000
#define MOD 1000000007
#define LL long long
#define pi acos(-1.0)

using namespace std;

int a, b, c;
int dis[MAXN][MAXN];
vector<string> vec;
int pre[MAXN * MAXN];
int num[MAXN][MAXN];

struct Node {
  int a;
  int b;
};

int bfs() {
  memset(dis, -1, sizeof(dis));
  memset(pre, -1, sizeof(pre));
  memset(num, -1, sizeof(num));
  queue<Node> que;
  dis[0][0] = 0;
  num[0][0] = 0;
  Node t;
  t.a = 0, t.b = 0;
  que.push(t);
  int cnt = 0;
  vec.push_back("*");
  while (!que.empty()) {
    Node p = que.front();
    que.pop();
    if (p.a == c || p.b == c) {
      cout << dis[p.a][p.b] << endl;
      vector<string> v;
      int s = num[p.a][p.b];
      v.push_back(vec[s]);
      while (s != -1 && s != 0) {
        s = pre[s];
        v.push_back(vec[s]);
      }
      for (int i = v.size() - 2; i >= 0; --i)
        cout << v[i] << endl;
      return dis[p.a][p.b];
    }
    if (dis[a][p.b] == -1) {
      vec.push_back("FILL(1)");
      cnt++;  
      num[a][p.b] = cnt;
      pre[cnt] = num[p.a][p.b];
      dis[a][p.b] = dis[p.a][p.b] + 1;
      Node temp;
      temp.a = a, temp.b = p.b;
      que.push(temp);
    }
    if (dis[p.a][b] == -1) {
      vec.push_back("FILL(2)");
      cnt++;
      num[p.a][b] = cnt;
      pre[cnt] = num[p.a][p.b];
      dis[p.a][b] = dis[p.a][p.b] + 1;
      Node temp;
      temp.a = p.a, temp.b = b;
      que.push(temp);
    }
    if (dis[0][p.b] == -1) {
      vec.push_back("DROP(1)");
      cnt++;
      num[0][p.b] = cnt;
      pre[cnt] = num[p.a][p.b];
      dis[0][p.b] = dis[p.a][p.b] + 1;
      Node temp;
      temp.a = 0, temp.b = p.b;
      que.push(temp);
    }
    if (dis[p.a][0] == -1) {
      vec.push_back("DROP(2)");
      cnt++;
      num[p.a][0] = cnt;
      pre[cnt] = num[p.a][p.b];
      dis[p.a][0] = dis[p.a][p.b] + 1;
      Node temp;
      temp.a = p.a, temp.b = 0;
      que.push(temp);
    }
    if (dis[max(0, p.a - (b - p.b))][min(b, p.b + p.a)] == -1) {
      vec.push_back("POUR(1,2)");
      cnt++;
      num[max(0, p.a - (b - p.b))][min(b, p.b + p.a)] = cnt;
      pre[cnt] = num[p.a][p.b];
      dis[max(0, p.a - (b - p.b))][min(b, p.b + p.a)] = dis[p.a][p.b] + 1;
      Node temp;
      temp.a = max(0, p.a - (b - p.b)), temp.b = min(b, p.b + p.a);
      que.push(temp);
    }
    if (dis[min(a, p.a + p.b)][max(0, p.b - (a - p.a))] == -1) {
      vec.push_back("POUR(2,1)");
      cnt++;
      num[min(a, p.a + p.b)][max(0, p.b - (a - p.a))] = cnt;
      pre[cnt] = num[p.a][p.b];
      dis[min(a, p.a + p.b)][max(0, p.b - (a - p.a))] = dis[p.a][p.b] + 1;
      Node temp;
      temp.a = min(a, p.a + p.b), temp.b = max(0, p.b - (a - p.a));
      que.push(temp);
    }
  }
  return -1;
}

int main() {
  std::ios::sync_with_stdio(false);
  while (cin >> a >> b >> c) {
    vec.clear();
    int num = bfs();
    if (num == -1) {
      cout << "impossible\n";
    }
  }
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值