I. 驾驶卡丁车(状压 + 模拟)
Posted jpphy0
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了I. 驾驶卡丁车(状压 + 模拟)相关的知识,希望对你有一定的参考价值。
问题
- 驾驶卡丁车 - https://codeforces.com/gym/103389/problem/I
- 2021年 CCPC 女生专场
分析
- 前进方向有8个
- 双重循环
- 状压:某个方格四周的平地及障碍物信息用8位二进制表示
代码
#include<bits/stdc++.h>
using namespace std;
const int mxn = 60;
int n, m, dir, step, x = 0, y, v, cnt;
int dx[8] = {0, -1, -1, -1, 0, 1, 1, 1}, dy[8] = {1, 1, 0, -1, -1, -1, 0, 1};
char g[mxn][mxn], cmd;
void solve(){
int tx = x+dx[dir], ty = y+dy[dir];
if(g[tx][ty] == '#') step = 0, v = 0, printf("Crash! ");
else if((dir & 1) == 0) x = tx, y = ty, --step;
else if(g[x+dx[(dir+1)%8]][y+dy[(dir+1)%8]] == '.'||g[x+dx[(dir+7)%8]][y+dy[(dir+7)%8]] == '.')
x = tx, y = ty, --step;
else step = 0, v = 0, printf("Crash! ");
}
int main(){
scanf("%d%d", &n, &m);
for(int i = 0; i <= m+1; ++i) g[0][i] = g[n+1][i] = '#';
for(int i = 1; i <= n; ++i){
scanf("%s", g[i]+1), g[i][0] = g[i][m+1]='#';
if(x) continue;
for(int j = 1; j <= m; ++j) if(g[i][j]=='*') x = i, y = j, g[i][j] = '.';
}
scanf("%d%c", &cnt, &cmd), dir = 2, v = 0;
while(scanf("%c", &cmd), cmd != '\\n'){
if(cmd == 'L') ++dir, dir %= 8;
else if(cmd == 'R') dir += 7, dir %= 8;
else if(cmd == 'U') ++v;
else v = v == 0 ? 0 : v-1;
step = v;
while(step) solve();
printf("%d %d\\n", x, y);
}
return 0;
}
- 状压
#include<bits/stdc++.h>
using namespace std;
const int mxn = 60;
int n, m, dir, step, x, y, v, g[mxn][mxn], cnt;
int dx[8] = {0, -1, -1, -1, 0, 1, 1, 1}, dy[8] = {1, 1, 0, -1, -1, -1, 0, 1};
char type[mxn][mxn], cmd;
void solve(){
if(dir & 1){
if(g[x][y] & (1 << dir))
step = 0, v = 0, printf("Crash! ");
else if((g[x][y] & (1 << (dir+7)%8)) && (g[x][y] & (1 << (dir+1)%8)))
step = 0, v = 0, printf("Crash! ");
else x += dx[dir], y += dy[dir], --step;
}
else{
if(g[x][y] & (1 << dir)) step = 0, v = 0, printf("Crash! ");
else x += dx[dir], y += dy[dir], --step;
}
}
int main(){
memset(g, 0, sizeof g);
scanf("%d%d", &n, &m);
for(int i = 0; i <= m+1; ++i) type[0][i] = type[n+1][i] = '#';
for(int i = 1; i <= n; ++i)
scanf("%s", type[i]+1), type[i][0] = type[i][m+1]='#';
for(int i = 0; i <= n+1; ++i)
for(int j = 0; j <= m+1; ++j)
if(type[i][j] == '*') x = i, y = j, type[i][j] = 0;
else if(type[i][j] == '.') type[i][j] = 0;
else type[i][j] = 1;
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j)
for(int k = 0; k < 8; ++k) g[i][j] |= type[i+dx[k]][j+dy[k]] << k;
scanf("%d%c", &cnt, &cmd), dir = 2, v = 0;
for(int i = 1; i <= cnt; ++i){
scanf("%c", &cmd);
if(cmd == 'L') ++dir, dir %= 8;
else if(cmd == 'R') dir += 7, dir %= 8;
else if(cmd == 'U') ++v;
else v = v == 0 ? 0 : v-1;
step = v;
while(step) solve();
printf("%d %d\\n", x, y);
}
return 0;
}
以上是关于I. 驾驶卡丁车(状压 + 模拟)的主要内容,如果未能解决你的问题,请参考以下文章
2021年CCPC女生专场(淄博)I. 驾驶卡丁车(状压 + 模拟)
2021年CCPC女生专场(淄博)I. 驾驶卡丁车(状压 + 模拟)
LeetCode810. 黑板异或游戏/455. 分发饼干/剑指Offer 53 - I. 在排序数组中查找数字 I/53 - II. 0~n-1中缺失的数字/54. 二叉搜索树的第k大节点(代码片段