2021 RoboCom 世界机器人开发者大赛-本科组(复赛)

pta题解

7-1 冒险者分队 (20 分)

2021 RoboCom 世界机器人开发者大赛-本科组(复赛)_第1张图片
2021 RoboCom 世界机器人开发者大赛-本科组(复赛)_第2张图片
pta微信公众号里讲的很明白,题解中都是20的倍数,20变2等比较容易想到。
关键的两点在于:
1.+2与-1, -2与+1 模3同余
2.一般化处理,不妨设a1 < a2 < 0 < a3
AC代码:
代码没了,但挺简单,跟普通01背包基本一样 这里有一篇博客,里面有01背包的模板

傻逼pta没了

7-2 拼题A打卡奖励 (25 分)

2021 RoboCom 世界机器人开发者大赛-本科组(复赛)_第3张图片

AC代码:

傻逼pta没了

7-3 快递装箱 (25 分)

。。。
鸡巴题,爷读了一个小时妹看明白啥意思,滚呐(咬牙切齿花少北.jpg)

7-4 塔防游戏 (30 分)

2021 RoboCom 世界机器人开发者大赛-本科组(复赛)_第4张图片分析:
跟上面说的差不多,先跑一个dij,这样的话每队僵尸的路线就得到了
我的代码按照这个顺序写的:
1.建图(其实每太必要)
2.跑dij并记录路径
3.处理每一队僵尸,确定他们的起点,数量并入队
4.时间t,模拟
5.打印答案。
然后27分,有一个点妹过去,看了std之后大体知道原因,但是懒得修改惹,错的原因如果好几个僵尸队,同时攻打一个东西,这个东西的防御力为1,那么我的做法是在这个时刻被我先遍历的那队僵尸比较倒霉,这队死一个,然后防御力变为0,其他那几队这这个时刻可以直接过去,实际应该是每队僵尸都要死一个。
另外,第一发25分,错因是基地没了直接停下了,但是,就像上面说的那样,在这个时刻有很多队僵尸需要处理,我只是处理到这一队的时候基地就没了,但是剩下的那几队僵尸还是会活动的。
妹AC代码:

#include 

using namespace std;

int n, m, t, tot;
int x, y;
int mp[105][105];
int head[105][105];
struct node
{
    int x, y, l, ne;
}edge[80050];
int dis[105][105];
bool vis[105][105];
int be_x, be_y, be_sum;
struct node1
{
    int x, y, l;
    bool operator < (const node1 &b) const
    {
        return l > b.l;
    }
}now;
priority_queue<node1> q;
pair<int,int> pre[105][105];
struct node2
{
    int x, y, sum, t;
}no;
node2 ne;
queue<node2> qi;
bool flag;

void addedge(int x, int y, int tx, int ty, int l)
{
    edge[++tot].x = tx;
    edge[tot].y = ty;
    edge[tot].l = l;
    edge[tot].ne = head[x][y];
    head[x][y] = tot;
}

void init()//建图,并找到基地
{
    for(int i = 1; i <= n; ++i)
    {
        for(int j = 1; j <= m; ++j)
        {
            if((i-1) >= 1) addedge(i, j, i - 1, j, mp[i-1][j]);
            if((j-1) >= 1) addedge(i, j, i, j - 1, mp[i][j-1]);
            if((i+1) <= n) addedge(i, j, i + 1, j, mp[i+1][j]);
            if((j+1) <= m) addedge(i, j, i, j + 1, mp[i][j+1]);
            if(mp[i][j] < 0)
            {
                be_x = i;
                be_y = j;
                be_sum = -mp[i][j];
            }
        }
    }
}

void djk()//跑dij
{
    memset(dis, 0x3f, sizeof(dis));

    dis[be_x][be_y] = 0;
    q.push({be_x, be_y, 0});

    while(!q.empty())
    {
        now = q.top();
        q.pop();

        if(vis[now.x][now.y]) continue;
        vis[now.x][now.y] = true;

        for(int i = head[now.x][now.y]; i; i = edge[i].ne)
        {
            x = edge[i].x;
            y = edge[i].y;
            if(dis[x][y] > dis[now.x][now.y] + edge[i].l)
            {
                dis[x][y] = dis[now.x][now.y] + edge[i].l;
                pre[x][y].first = now.x;//记录路径
                pre[x][y].second = now.y;
                q.push({x, y, dis[x][y]});
            }
        }
    }
}

void dio_qiqi()//将所有的僵尸队入队
{
    for(int i = 1; i <= m; ++i)
    {
        pre[0][i].first = 1;
        pre[0][i].second = i;
        pre[n+1][i].first = n;
        pre[n+1][i].second = i;
        if(mp[0][i]) qi.push({0, i, mp[0][i], 0});
        if(mp[n+1][i]) qi.push({n+1, i, mp[n+1][i], 0});
    }
    for(int i = 1; i <= n; ++i)
    {
        pre[i][0].first = i;
        pre[i][0].second = 1;
        pre[i][m+1].first = i;
        pre[i][m+1].second = m;
        if(mp[i][0]) qi.push({i, 0, mp[i][0], 0});
        if(mp[i][m+1]) qi.push({i, m+1, mp[i][m+1], 0});
    }
}

void print()
{
    for(int i = 1; i <= n; ++i)
    {
        for(int j = 1; j <= m; ++j)
        {
            printf("%d", mp[i][j]);
            if(j == m) putchar('\n');
            else putchar(' ');
        }
    }
    if(flag) printf("Game Over");
}

void dio()//这个有错。。。懒得改
{
    int la_t = -99;
    while(!qi.empty())
    {
        no = qi.front();
        qi.pop();
        if(no.t >= t || no.t == la_t + 1) return ;
        if(no.sum == 0) continue;
        ne.x = pre[no.x][no.y].first;
        ne.y = pre[no.x][no.y].second;
        if(ne.x == be_x && ne.y == be_y)
        {
            --be_sum;
            if(la_t == no.t) continue;
            if(!be_sum)
            {
                mp[be_x][be_y] = 0;
                flag = true;
                la_t = no.t;
                continue;
            }
            mp[be_x][be_y] = -be_sum;
            ne.sum = no.sum - 1;
            ne.t = no.t + 1;
            ne.x = no.x;
            ne.y = no.y;
            qi.push(ne);
            continue;
        }
        if(!mp[ne.x][ne.y])
        {
            ne.sum = no.sum;
            ne.t = no.t + 1;
            qi.push(ne);
        }
        else
        {
            --mp[ne.x][ne.y];
            ne.sum = no.sum - 1;
            ne.t = no.t + 1;
            ne.x = no.x;
            ne.y = no.y;
            qi.push(ne);
        }
    }
}

int main()
{
    scanf("%d%d%d", &n, &m, &t);
    for(int i = 0; i < n + 2; ++i)
        for(int j = 0; j < m + 2; ++j)
            scanf("%d", &mp[i][j]);
    init();
    djk();
    dio_qiqi();
    dio();
    print();
    return 0;
}

你可能感兴趣的:(题解,图论,01背包,RoboCom机器人开发者大赛,acm竞赛,c++)