pta题解
pta微信公众号里讲的很明白,题解中都是20的倍数,20变2等比较容易想到。
关键的两点在于:
1.+2与-1, -2与+1 模3同余
2.一般化处理,不妨设a1 < a2 < 0 < a3
AC代码:
代码没了,但挺简单,跟普通01背包基本一样 这里有一篇博客,里面有01背包的模板
傻逼pta没了
AC代码:
傻逼pta没了
。。。
鸡巴题,爷读了一个小时妹看明白啥意思,滚呐(咬牙切齿花少北.jpg)
分析:
跟上面说的差不多,先跑一个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;
}