Find a way
思路:这一题看似简单其实不然,有很多特办条件,如果当这个M和Y都在KFC的时候就会导致步数为0 ,或者可以这样说:只有两人都能到达才能算入答案。
我们可以使用bfs来写这道题,这不过这道题目不需要加入最后的目的地,直接将其全部bfs完,然后使用一个二维数组来存每一个地方的步数就可以了,所以需要两次bfs,需要两个二维数组来存步数。
然后使用一个结构体数组来存终点的位置
我犯下的错误:第一就是bfs还是不能够熟练的使用,我们需要一个变量来存队首,还需要一个变量存改变过后的值,所以我们要插入的值是这个改变的值,而来存队首的变量的值是不能改变的,我经常将不能改变的值改变了,这就导致bfs最后所存下来的图会随着变量的增加而改变。
错误的代码:我将不能改变的变量a改变了,并且还将a给插入到队列了,这就会导致我们存在二位数组中步数就会错,好在我遇到这一题,不然我永远不会知道我错在哪里
应该将b作为可以改变的对象,只对b进行改变,然后再将b入队。所以正确的代码应该是
这里还有一个坑点就是输入的问题:时间超限这个问题卡了我很久,一直都不知道是错在哪里。后来在一个大佬的帮助下发现这个输入应该放在while循环中,应该是while(cin >> n >> m) 这样输入就不会导致时间超限,如果将这个放在循环里面就会导致时间超限。
最后一个坑点就是判断输出的问题,我们进行输出的时候就需要进行一个判断,这个判断应该放在最后输出的位置,当M和Y无法同时到达终点的时候不能进行输出。
最终代码如下:
#include<iostream>
#include<string>
#include<map>
#include<queue>
#include<string.h>
#define N 1000000
#define M 350
int n, m,cnt = 0;
using namespace std;
int dx[] = { -1,1,0,0 };
int dy[] = { 0,0,-1,1 };
struct node
{
int x, y;
}exit_[N];
int step_M[M][M];
int step_Y[M][M];
bool vis[M][M];
char maze[M][M];
int M_x, M_y;
int Y_x, Y_y;
queue<node>q;
void bfs_M(int sx, int sy)
{
memset(vis, 0, sizeof(vis));
memset(step_M, 0, sizeof(step_M));
struct node a, b;
a.x = sx;
a.y = sy;
step_M[a.x][a.y] = 0;
vis[sx][sy] = 1;
q.push(a);
while (!q.empty())
{
a = q.front();
q.pop();
vis[a.x][a.y] = 1;
for (int i = 0; i <4; i++) {
int tx = a.x + dx[i];
int ty = a.y + dy[i];
if (tx <= n && tx >= 1 && ty <= m && ty >= 1 && vis[tx][ty] == 0 && maze[tx][ty]!='#') {
vis[tx][ty] = 1;
step_M[tx][ty] = step_M[a.x][a.y] + 1;
b.x = tx;
b.y = ty;
q.push(b);
}
}
}
}
void bfs_Y(int sx, int sy)
{
memset(vis, 0, sizeof(vis));
memset(step_Y, 0, sizeof(step_Y));
struct node a, b;
a.x = sx;
a.y = sy;
step_Y[a.x][a.y] = 0;
vis[sx][sy] = 1;
q.push(a);
while (!q.empty())
{
a = q.front();
q.pop();
vis[a.x][a.y] = 1;
for (int i = 0; i < 4; i++) {
int tx = a.x + dx[i];
int ty = a.y + dy[i];
if (tx <= n && tx >= 1 && ty <= m && ty >= 1 && vis[tx][ty] == 0&&maze[tx][ty]!= '#') {
vis[tx][ty] = 1;
step_Y[tx][ty] = step_Y[a.x][a.y] + 1;
b.x = tx;
b.y = ty;
q.push(b);
}
}
}
}
int main()
{
while (cin >> n >> m)
{
cnt = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> maze[i][j];
if (maze[i][j] == 'Y') {
Y_x = i;
Y_y = j;
}
if (maze[i][j] == 'M') {
M_x = i;
M_y = j;
}
if (maze[i][j] == '@') {
exit_[++cnt].x = i;
exit_[cnt].y = j;
}
}
getchar();
}
bfs_M(M_x, M_y);
bfs_Y(Y_x, Y_y);
int ans = 2147483647;
for (int i = 1; i <= cnt; i++) {
if (step_M[exit_[i].x][exit_[i].y] != 0 && step_Y[exit_[i].x][exit_[i].y] != 0) {
int t_M = step_M[exit_[i].x][exit_[i].y];
int t_Y = step_Y[exit_[i].x][exit_[i].y];
int t = t_M + t_Y;
ans = min(ans, t);
}
}
cout << 11*ans << endl;
}
}
/*
1.在主函数中输入的时候就将出口位置进行标记,使用一个结构体数组进行标记
2.对于M和Y只需要进行一次bfs即可。
*/
pots
思路:这里一共由三种操作,但是实际上是有6种操作,因为有两个杯子。我们把具体的操作抽象化为数据的操作,我们假设一个杯子的容积为a,那么fill的操作就是令a = a,drop就是使a = 0,
对于第三种操作需要具体考虑若原本a杯子的水加上b杯子的水已经超过了a的容积,那么只需要将a杯子的最大容积减去a杯子现有的容积,然后令a杯子的水等于最大容积,b杯子减去之前算过的a杯子的最大容积减去a杯子现有的容积。第二种情况:就是当b杯子装进去的水小于a杯子最大容积减去a杯子现有的水那么就使a杯子的水等于a杯子现有的水加上b杯子剩余的水。
对于b也同理。
这6种操作当成队列一次入队进行可行性判断,其终止条件是如果有一个杯子的水等于目标杯子那么就跳出循环。
#include<iostream>
#include<string>
#include<map>
#include<queue>
#include<string.h>
using namespace std;
int A, B, C;
bool vis[120][120];
struct node
{
int a;
int b;
int step[100005];
int sum;
};
bool bfs()
{
memset(vis, 0, sizeof(vis));
queue<node> q;
node x, y;
x.a = x.b = x.sum = 0;
vis[x.a][x.b] = 1;
q.push(x);
while (!q.empty())
{
x = q.front();
q.pop();
if (x.a == C || x.b == C) {
cout << x.sum << endl;
for (int i = 1; i <= x.sum; i++) {
if (x.step[i] == 1) cout << "FILL(1)" << endl;
if (x.step[i] == 2) cout << "FILL(2)" << endl;
if (x.step[i] == 3) cout << "DROP(1)" << endl;
if (x.step[i] == 4) cout << "DROP(2)" << endl;
if (x.step[i] == 5) cout << "POUR(1,2)" << endl;
if (x.step[i] == 6) cout << "POUR(2,1)" << endl;
}
return true;
}
for (int i = 1; i <= 6; i++) {
y = x;
if (i == 1) y.a = A;
if (i == 2) y.b = B;
if (i == 3) y.a = 0;
if (i == 4) y.b = 0;
if (i == 5) {
if (x.a + x.b <= B) {
y.b = x.a + x.b;
y.a = 0;
}
else {
y.a = y.a - (B - y.b);
y.b = B;
}
}
if (i == 6) {
if (x.a + x.b <= A) {
y.a = x.a + x.b;
y.b = 0;
}
else {
y.b = y.b - (A - y.a);
y.a = A;
}
}
if (!vis[y.a][y.b]) {
vis[y.a][y.b] = 1;
y.sum = x.sum + 1;
y.step[y.sum] = i;
q.push(y);
}
}
}
return false;
}
int main()
{
cin >> A >> B >> C;
if (!bfs())
{
cout << "impossible" << endl;
}
return 0;
}