2021年CCPC女生专场(淄博)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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jpphy0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值