I. 驾驶卡丁车(状压 + 模拟)

Posted jpphy0

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了I. 驾驶卡丁车(状压 + 模拟)相关的知识,希望对你有一定的参考价值。

问题

分析

  • 前进方向有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. 驾驶卡丁车(状压 + 模拟)

怎么用方向盘玩游戏?

1015升级版跑跑卡丁车

LeetCode810. 黑板异或游戏/455. 分发饼干/剑指Offer 53 - I. 在排序数组中查找数字 I/53 - II. 0~n-1中缺失的数字/54. 二叉搜索树的第k大节点(代码片段

HDU4057 Rescue the Rabbit(AC自动机+状压DP)