一道模拟题,想要ac的话还是挺麻烦的。简单说一下我的思路,不断用找下一个对手所在的城市,如果不能到达该城市或找不到符合条件的对手,判断输赢,否则,前往该城市。到达该城市后,判断能不能在时间结束前干掉对手,如果不行,输出Game over,否则,干掉对手,更新联盟,然后判断能不能待到第二天,如果可以(当且仅当当前城市还有人),干掉剩余人,在重新找对手,否则,直接重新找对手,且下次对手不能为当前城市。
我的代码从day0开始的,所以如果开局就胜利或输,应该令day++;同时这也是测试点8考察的点。
测试点9:如果你在一个城市中,且不能待到第二天,你要保证你下一个找的对手不在你当前这个城市中。
ac代码:
#include<bits/stdc++.h>
#define ll long long
#define ios ios::sync_with_stdio(0)
#define pii pair<int,int>
#define x first
#define y second
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dwn(i,a,b) for(int i=a;i>=b;i--)
#define repp(i,a,b) for(int i=a;i<b;i++)
#define dwnn(i,a,b) for(int i=a;i>b;i--)
#define lowbit(x) x&-x
#define mm memset
#define endl '\n'
#define INF 0x3f3f3f3f
#define debug(x) cout<<"x = "<<x<<endl
#define PB push_back
using namespace std;
const int N = 1e6 + 5,M = 205;
int n,m,e,d,mp[M][M],path[M][M],day,lastcity = -1;
bool lose[N];
vector<pii> city[M];
pii p[N];
void input() {
lose[0] = true;
mm(mp,INF,sizeof(mp));
mm(path,INF,sizeof(path));
cin>>n>>m>>e>>d;
repp(i,0,n) {
cin>>p[i].x>>p[i].y;
city[p[i].x].PB({i,p[i].y});
}
rep(i,1,e) {
int u,v,w;
cin>>u>>v>>w;
mp[u][v] = mp[v][u] = w;
mp[u][u] = mp[v][v] = 0;
path[u][u] = path[v][v] = 0;
path[u][v] = path[v][u] = 1;
}
repp(k,0,m) {
repp(i,0,m) {
repp(j,0,m) {
if(mp[i][j] > mp[i][k] + mp[k][j]) {
mp[i][j] = mp[i][k] + mp[k][j];
path[i][j] = path[i][k] + path[k][j];
}
else if(mp[i][j] == mp[i][k] + mp[k][j]
&& path[i][j] > path[i][k] + path[k][j]) {
path[i][j] = path[i][k] + path[k][j];
}
}
}
}
}
bool iswin() {
repp(i,1,n) {
if(!lose[i]) return false;
}
return true;
}
int find() {
bool isb = false;
int myable = p[0].y,mycity = p[0].x,ne = 0;
int mia = INF,mib = INF,mic = INF,mid = INF;
repp(i,1,n) {
if(lose[i]) continue;
if(p[i].y > myable) {
isb = true;
continue;
}
if(p[i].x == lastcity) {
continue;
}
int dif = abs(p[i].y - myable);
int dis = mp[mycity][p[i].x];
int num = path[mycity][p[i].x];
int id = p[i].x;
if(dif < mia) {
mia = dif;
mib = dis;
mic = num;
mid = id;
ne = i;
}
else if(dif == mia) {
if(dis < mib) {
mia = dif;
mib = dis;
mic = num;
mid = id;
ne = i;
}
else if(dis == mib) {
if(num < mic) {
mia = dif;
mib = dis;
mic = num;
mid = id;
ne = i;
}
else if(num == mic) {
if(id < mid) {
mia = dif;
mib = dis;
mic = num;
mid = id;
ne = i;
}
}
}
}
}
if(ne == 0) {
if(isb) {
day ++;
printf("Lose on day %d with %d.",day,p[0].y);
}
else {
if(day == 0)
printf("WIN on day %d with %d!",day+1,p[0].y);
else
printf("WIN on day %d with %d!",day,p[0].y);
}
return -1;
}
if(day + mp[p[0].x][p[ne].x] > d) {
printf("Game over with %d.",p[0].y);
return -1;
}
if(p[0].x != p[ne].x) {
printf("Move from %d to %d.\n",p[0].x,p[ne].x);
lastcity = p[ne].x;
day += mp[p[0].x][p[ne].x];
if(day > d) return -1;
}
return ne;
}
void update(int ne) {
day ++;
if(day > d) {
printf("Game over with %d.",p[0].y);
return ;
}
printf("Get %d at %d on day %d.\n",p[ne].y,p[ne].x,day);
lose[ne] = true;
p[0].x = p[ne].x;
p[0].y += p[ne].y;
int sum = 0;
bool f = true;
repp(i,0,city[p[ne].x].size()) {
int able = city[p[ne].x][i].y;
int id = city[p[ne].x][i].x;
if(lose[id]) continue;
if(able > p[0].y) {
f = false;
continue;
}
else {
sum += able;
lose[id] = true;
}
}
if(sum > p[0].y) f = false;
if(f && sum != 0) { // 可以待到第二天
day ++;
if(day > d) {
printf("Game over with %d.",p[0].y);
return ;
}
printf("Get %d at %d on day %d.\n",sum,p[ne].x,day);
p[0].y += sum;
}
if(!f) { // 不能待到第二天
if(sum != 0) {
p[n].x = p[ne].x,p[n].y = sum;
city[p[ne].x].PB({n,sum});
n ++;
}
}
}
void solve() {
input();
while(day <= d) {
int ne = find();
if(ne == -1) break;
update(ne);
}
}
int main() {
ios;
solve();
return 0;
}