NC17624 J.Ants(模拟)
目录
Description
有一个长度为 \([0,1e9+1]\) 的木棍,上面有 \(n\) 个蚂蚁,但是在木棍的端点有两个障碍物,牢固值分别为 \(A, B\),如果有一个蚂蚁装上障碍物,对应端点的牢固值减一,当 \(A/B=0\) 时,障碍物刚好消失;
现在这 \(n\) 个蚂蚁分别向左或向右行走,如果碰到了蚂蚁或者是障碍物都会掉头,每只蚂蚁速度为 \(1m/s\) ,求多长时间,所有蚂蚁都会掉下去
State
\(1<=n<=10^6\)
\(1<=A<=B<=10^9\)
\(1<=a_1,a_2...a_n<=10^9\)
\(d_1,d_2...d_n∈{0,1}\)
Input
2 2 4
2 3
0 1
Output
4000000001
Solution
题目需要一个小技巧,我们不考虑蚂蚁相撞,这样当第 \(i\) 只蚂蚁回到原来的位置是,其需要花费 \(2e9+2\) 的时间,并且对两端的障碍物都造成一次伤害,这样 \(A,B\) 的范围就降为了 \(1e6\)
而此时所有的蚂蚁还是处于原来的状态,剩下的就是模拟了
假设有一个数组 \(p[i]\) 表示的是到其所对应的端点的距离是多少,然后按升序排序,其中有一个蚂蚁比较特殊,即 \(x\),任意的 \(i>x\) ,都会掉下去
而这个 \(x\) 所花费的时间就是这次路程的最长时间,对于其之前还没有掉下去的蚂蚁来说,需要对其进行更新其当前位置
Code
const int N = 1e6 + 5;
int n, m, k, _;
// int a[N];
pli p[N];
ll sum[N];
ll calc(int a, int b)
{
ll ans = 0;
while(true){
int tot = 0;
ll maxx = 0;
for(int i = 1; i <= n; i ++){
if(p[i].se == -1) continue;
sum[i] = p[i].fi;
maxx = p[i].fi; //最长时间
int id = p[i].se;
if(id == 1){
if(b == 0){
p[i].se = -1;
}
else{
b --;
p[i] = {1e9 + 1, 0};
}
}
else if(id == 0){
if(a == 0){
p[i].se = -1;
}
else{
a --;
p[i] = {1e9 + 1, 1};
}
}
}
ans += maxx;
for(int i = 1; i <= n; i ++){
p[i].fi = p[i].fi - maxx + sum[i];
if(p[i].se == -1)
tot ++;
}
if(tot == n) break;
}
return ans;
}
signed main()
{
// IOS;
int a, b;
while(~ sddd(n, a, b)){
ll ans = 0;
rep(i, 1, n){
sll(p[i].fi);
}
rep(i, 1, n){
sd(p[i].se);
}
rep(i, 1, n){
if(p[i].se == 1){
p[i].fi = 1e9 + 1 - p[i].fi;
}
}
sort(p + 1, p + 1 + n);
int minn = min(a, b);
ll k = minn / n;
a -= k * n;
b -= k * n;
ans += 2 * k * (ll)(1e9 + 1);
ans += calc(a, b);
pll(ans);
}
// PAUSE;
return 0;
}

浙公网安备 33010602011771号