记一道弱智题
P2033 Chessboard Dance
今天集训第四天,遇到这道模拟题。
我搞错了一大问题。首先我以为移动是整行移动,但显然不是的。于是我就开始想这个怎么处理:
我想是先碰到之后让箱子作为P,继续往后推,再碰到箱子……最后回溯。这是可怕的递归,函数是 MOVE(x, y, Steps_rem)
。奈何码力不足,写了一下午。
回家之后就会了 😅,其实递归是可以的,但其实只需要走一步,不需要搞一个Step变量,纯粹是问题复杂化。
但是呢,也有一些东西要注意:平面坐标系和数组意义的坐标系是不一样的,把人烦死。
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define CHECK cout<<"WALKED"<<endl;
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0' && ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;}
ll qpow(ll a, ll b, ll mod){ll res = 1; while (b > 0){if (b & 1) res = res * a % mod;a = a * a % mod; b >>= 1; } return res;}
using namespace std;
char mp[100][100];
string opt, optf;
struct Person {
int x, y;
int dx, dy;
}P;
bool check(int tx, int ty)
{
if (tx >= 1 && tx <= 8 && ty >= 1 &&ty <= 8) return true;
return false;
}
void MOVE(int nowx, int nowy)
{
int nx = nowx + P.dx;
int ny = nowy + P.dy;
if (!check(nx, ny))
return;
if (mp[nx][ny] != '.') {
MOVE(nx, ny);
}
mp[nx][ny] = mp[nowx][nowy];
mp[nowx][nowy] = '.';
P.x = nx;
P.y = ny;
}
int main()
{
for (int i = 1; i <= 8; i++)
for (int j = 1; j <= 8; j++) {
cin >> mp[i][j];
if (mp[i][j] == '^') P = {i, j, -1, 0};
else if (mp[i][j] == '<') P = {i, j, 0, -1};
else if (mp[i][j] == 'v') P = {i, j, 1, 0};
else if (mp[i][j] == '>') P = {i, j, 0, 1};
}
int n;
while (true)
{
opt = "", optf = "";
cin >> opt;
if (opt == "#") break;
if (opt == "turn") cin >> optf;
if (opt == "move") cin >> n;
if (opt == "move") {
for (int i = 1; i <= n; i++) {
MOVE(P.x, P.y);
}
}
if (optf == "left") {
if (P.dx == -1 && P.dy == 0) P.dx = 0, P.dy = -1;
else if (P.dx == 0 && P.dy == -1) P.dx = 1, P.dy = 0;
else if (P.dx == 1 && P.dy == 0) P.dx = 0, P.dy = 1;
else if (P.dx == 0 && P.dy == 1) P.dx = -1, P.dy = 0;
}
else if (optf == "right") {
if (P.dx == -1 && P.dy == 0) P.dx = 0, P.dy = 1;
else if (P.dx == 0 && P.dy == 1) P.dx = 1, P.dy = 0;
else if (P.dx == 1 && P.dy == 0) P.dx = 0, P.dy = -1;
else if (P.dx == 0 && P.dy == -1) P.dx = -1, P.dy = 0;
}
else if (optf == "back") {
if (P.dx == 1 && P.dy == 0) P.dx = -1, P.dy = 0;
else if (P.dx == 0 && P.dy == 1) P.dx = 0, P.dy = -1;
else if (P.dx == -1 && P.dy == 0) P.dx = 1, P.dy = 0;
else if (P.dx == 0 && P.dy == -1) P.dx = 0, P.dy = 1;
}
}
for (int i = 1; i <= 8; i++) {
for (int j = 1; j <= 8; j++) {
if (i == P.x && j == P.y) {
if (P.dx == 1 && P.dy == 0) cout << 'v';
else if (P.dx == 0 && P.dy == 1) cout << '>';
else if (P.dx == -1 && P.dy == 0) cout << '^';
else if (P.dx == 0 && P.dy == -1) cout << '<';
continue;
}
cout << mp[i][j];
}cout<<endl;
}
return 0;
}
下面是WA代码纪念时刻:
// 模拟题
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define CHECK cout<<"WALKED"<<endl;
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0' && ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;}
ll qpow(ll a, ll b, ll mod){ll res = 1; while (b > 0){if (b & 1) res = res * a % mod;a = a * a % mod; b >>= 1; } return res;}
using namespace std;
char mp[100][100];
string opt, optf;
struct Person {
int x, y;
int dx, dy;
}P;
bool check(int tx, int ty)
{
if (tx >= 1 && tx <= 8 && ty >= 1 &&ty <= 8) return true;
return false;
}
void Pxy_change(int n)
{
if (P.dx == -1 && P.dy == 0) P.x = max(n * P.dx + P.x, 1);
else if (P.dx == 0 && P.dy == -1) P.y = max(n * P.dy + P.y, 1);
else if (P.dx == 1 && P.dy == 0) P.x = min(n * P.dx + P.x, 8);
else if (P.dx == 0 && P.dy == 1) P.y = min(n * P.dy + P.y, 8);
}
void MOVE(int nowx, int nowy, int Steps)
{
// printf("in:nowx=%d, nowy=%d, Steps_left=%d\n", nowx, nowy, Steps);
if (Steps <= 0) return;
int stx = nowx, sty = nowy;
int s, rem = Steps;
for (s = 0; s < Steps; s++) {
if (!check(nowx + P.dx, nowy + P.dy)) {
return;
}
nowx += P.dx;
nowy += P.dy;
if (mp[nowx][nowy] != '.')
break;
}
Steps -= s;
// printf("out:nowx=%d, nowy=%d, Steps_left=%d\n", nowx, nowy, Steps);
MOVE(nowx, nowy, Steps);
if (P.dx == -1 && P.dy == 0) mp[max(Steps * P.dx + P.x, 1)][nowy] = mp[stx][sty];
else if (P.dx == 0 && P.dy == -1) mp[nowx][max(Steps * P.dy + P.y, 1)] = mp[stx][sty];
else if (P.dx == 1 && P.dy == 0) mp[min(Steps * P.dx + P.x, 8)][nowy] = mp[stx][sty];
else if (P.dx == 0 && P.dy == 1) mp[nowx][min(Steps * P.dy + P.y, 8)] = mp[stx][sty];
mp[stx][sty] = '.';
}
int main()
{
for (int i = 1; i <= 8; i++)
for (int j = 1; j <= 8; j++) {
cin >> mp[i][j];
if (mp[i][j] == '^') P = {i, j, -1, 0};
else if (mp[i][j] == '<') P = {i, j, 0, -1};
else if (mp[i][j] == 'v') P = {i, j, 1, 0};
else if (mp[i][j] == '>') P = {i, j, 0, 1};
}
int n;
while (true)
{
opt = "", optf = "";
cin >> opt;
if (opt == "#") break;
if (opt == "turn") cin >> optf;
if (opt == "move") cin >> n;
if (opt == "move") {MOVE(P.x, P.y, n); Pxy_change(n);}
if (optf == "left") {
if (P.dx == -1 && P.dy == 0) P.dx = 0, P.dy = -1;
else if (P.dx == 0 && P.dy == -1) P.dx = 1, P.dy = 0;
else if (P.dx == 1 && P.dy == 0) P.dx = 0, P.dy = 1;
else if (P.dx == 0 && P.dy == 1) P.dx = -1, P.dy = 0;
}
else if (optf == "right") {
if (P.dx == -1 && P.dy == 0) P.dx = 0, P.dy = 1;
else if (P.dx == 0 && P.dy == 1) P.dx = 1, P.dy = 0;
else if (P.dx == 1 && P.dy == 0) P.dx = 0, P.dy = -1;
else if (P.dx == 0 && P.dy == -1) P.dx = -1, P.dy = 0;
}
else if (optf == "back") {
if (P.dx == 1 && P.dy == 0) P.dx = -1, P.dy = 0;
else if (P.dx == 0 && P.dy == 1) P.dx = 0, P.dy = -1;
else if (P.dx == -1 && P.dy == 0) P.dx = 1, P.dy = 0;
else if (P.dx == 0 && P.dy == -1) P.dx = 0, P.dy = 1;
}
}
for (int i = 1; i <= 8; i++) {
for (int j = 1; j <= 8; j++) {
if (i == P.x && j == P.y) {
if (P.dx == 1 && P.dy == 0) cout << 'v';
else if (P.dx == 0 && P.dy == 1) cout << '>';
else if (P.dx == -1 && P.dy == 0) cout << '^';
else if (P.dx == 0 && P.dy == -1) cout << '<';
continue;
}
cout << mp[i][j];
}cout<<endl;
}
return 0;
}