gym103117J. Ants
Posted Jozky86
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了gym103117J. Ants相关的知识,希望对你有一定的参考价值。
题意:
n个蚂蚁在长度为1e9+1的木棍上,第i个蚂蚁在ai位置上,朝向为0/1(0表示左,1表示右),如果蚂蚁相遇则彼此调转方向。木棍两侧分别有厚度为a和b的墙,蚂蚁每撞一次墙,墙的厚度就会减1,当墙撞没时,蚂蚁就会直接掉下去,问最后一个蚂蚁掉下去的时间?
题解:
模拟题
有几点注意:
- 蚂蚁相遇调转方向可以相当于方向没变
- 一个蚂蚁需要撞两次墙才能回到原先的位置(墙没撞开),相当于周期为2len,每个周期,每只蚂蚁会对两侧的墙各撞一次
- 所以我们可以将前面整数个周期都算完,最后就剩下一轮,直接模拟完事
思路很简单,但是最后一轮的模拟很麻烦,我和队友调了4个小时才改出来,但是发现网上有很多简易的方法
我们用两个队列分别存向左向右的蚂蚁,每次取出两个队列首的元素,比较两个元素谁离端点更近,更近的会先撞墙,然后掉头,加入另一个队列中,直到墙撞开
代码:
const int N = 2e6 + 5;
int n, a, b, p[N], d[N], L = 1e9 + 1;
LL s, ans;
LL q1[N], q2[N];
int hh = 1, tt, h = 1, t;
void inline work1() {
LL u = q1[hh++];
if (a) {
a--;
q2[++t] = u + L;
}
else {
ans=max(ans,u);
}
}
void inline work2() {
LL u = q2[h++];
if (b){
b--;
q1[++tt] = u + L;
}
else {
ans=max(ans, u);
}
}
int main() {
read(n), read(a), read(b);
for (int i = 1; i <= n; i++) read(p[i]);
for (int i = 1; i <= n; i++) read(d[i]);
LL tmp = min(a, b) / n;
a -= n * tmp, b -= tmp * n;
s = tmp * L * 2;
for (int i = 1; i <= n; i++)
if (d[i] == 0) q1[++tt] = p[i];//左
for (int i = n; i; i--)
if (d[i] == 1) q2[++t] = L - p[i];//右
while (hh <= tt || h <= t) {
if (h > t || (hh <= tt && q1[hh] < q2[h])) work1();//左边先到
else work2();
}
printf("%lld\\n", ans + s);
return 0;
}
我和队友的代码:
就是纯模拟,讨论四种情况
// Problem: Ants
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/17624/J
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
//#pragma GCC target("avx")
//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
//#pragma GCC optimize("Ofast")
// created by myq
#include <algorithm>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
typedef long long ll;
#define x first
#define y second
typedef pair<int, int> pii;
const int N= 1000010;
const int mod= 998244353;
#define int long long
int a[N];
int d[N];
int n, l, r;
signed main()
{
ios::sync_with_stdio(0);
cin >> n >> l >> r;
int len= 1e9 + 1;
int j= 0;
for (int i= 1; i <= n; i++) {
cin >> a[i];
}
int lcnt= 0;
int rcnt= 0;
int res1= 0;
int res2= 0;
for (int i= 1; i <= n; i++) {
cin >> d[i];
if (!d[i])
lcnt++, res1= max(res1, a[i]);
else
rcnt++, res2= max(res2, len - a[i]);
}
int tt= min(l / n, r / n);
int res= 0;
res+= 2 * len * tt;
l-= tt * n;
r-= tt * n;
if (l < lcnt && r < rcnt) {
// if (n == 11)
// cout << 1 << endl;
vector<int> vv;
vector<int> vv2;
for (int i= 1; i <= n; i++)
if (d[i])
vv2.push_back(len - a[i]);
for (int i= 1; i <= n; i++)
if (!d[i])
vv.push_back(a[i]);
int L= (l == 0 ? (vv.size() ? vv.back() : 0) : vv[l - 1] + len);
int R= (r == 0 ? (vv2.size() ? vv2[0] : 0) : vv2[(int)vv2.size() - r] + len);
res+= max(L, R);
}
else if (l < lcnt && r >= rcnt) {
// if (n == 11)
// cout << 2 << endl;
r-= rcnt;
vector<int> vv;
vector<int> vv2;
for (int i= 1; i <= n; i++)
if (d[i])
vv2.push_back(len - a[i]);
for (int i= 1; i <= n; i++)
if (!d[i])
vv.push_back(a[i]);
if (l) {
int tmp= vv[l - 1] + len;
int tmp2= 0;
int tmp3= 0;
if (rcnt) {
tmp2+= vv2[0] + len;
}
if (r) {
int tr= min(r, l);
tmp3= vv[tr - 1] + 2 * len;
}
res+= max({tmp, tmp2, tmp3});
}
else {
res+= max((vv2.size() ? vv2[0] + len : 0ll), vv.back());
}
}
else if (l >= lcnt && r < rcnt) {
// if (n == 11)
// cout << 3 << endl;
vector<int> vv;
vector<int> vv2;
l-= lcnt;
for (int i= 1; i <= n; i++)
if (d[i])
vv2.push_back(len - a[i]);
for (int i= 1; i <= n; i++)
if (!d[i])
vv.push_back(a[i]);
if (r) {
int tmp= 0;
int tmp2= vv2[vv2.size() - r] + len;
int tmp3= 0;
if (lcnt) {
tmp+= vv.back() + len;
}
if (l) {
int tr= min(l, r);
tmp3= 2 * len + vv2[vv2.size() - tr];
}
res+= max({tmp3, tmp, tmp2});
}
else {
res+= max((vv.size() ? len + vv.back() : 0ll), vv2[0]);
}
}
else if (l >= lcnt && r >= rcnt) {
// if (n == 11)
// cout << 4 << endl;
res+= len;
l-= lcnt;
r-= rcnt;
lcnt= 0;
rcnt= 0;
// if(n==87)
// cout<<res<<endl;
for (int i= 1; i <= n; i++) {
a[i]= len - a[i];
d[i]^= 1;
if (!d[i])
lcnt++;
else
rcnt++;
}
if (l < lcnt && r < rcnt) {
// if (n == 11) {
// cout << 41 << endl;
// cout << l << " " << r << endl;
// cout << lcnt << " " << rcnt << endl;
// }
vector<int> vv;
vector<int> vv2;
for (int i= 1; i <= n; i++)
if (d[i])
vv2.push_back(len - a[i]);
for (int i= 1; i <= n; i++)
if (!d[i])
vv.push_back(a[i]);
reverse(vv.begin(), vv.end());
reverse(vv2.begin(), vv2.end());
// sort(vv.begin(), vv.end());
// sort(vv2.begin(), vv2.end(), greater<int>());
// if(n==87)
// cout<<vv[l-1]+len<<" "<< vv2[(int)vv2.size() - r] + len<<" "<<vv.back()<<" "<<vv2[0]<<endl;
int L= (l == 0 ? (vv.size() ? vv.back() : 0) : vv[l - 1] + len);
int R= (r == 0 ? (vv2.size() ? vv2[0] : 0) : vv2[(int)vv2.size() - r] + len);
res+= max(L, R);
}
else if (l < lcnt && r >= rcnt) {
// if (n == 11)
// cout << 42 << endl;
r-= rcnt;
vector<int> vv;
vector<int> vv2;
for (int i= 1; i <= n; i++)
if (d[i])
vv2.push_back(len - a[i]);
for (int i= 1; i <= n; i++)
if (!d[i])
vv.push_back(a[i]);
reverse(vv.begin(), vv.end());
reverse(vv2.begin(), vv2.end());
if (l) {
// if(n==59)
// cout<<l<<" "<<r<<" "<<lcnt<<" "<<rcnt<<endl;
int tmp= vv[l - 1] + len;
int tmp2= 0;
int tmp3= 0;
if (rcnt) {
tmp2+= vv2[0] + len;
}
if (r) {
int tr= min(r, l);
tmp3= vv[tr - 1] + 2 * len;
}
res+= max({tmp, tmp2, tmp3});
}
else {
res+= max((vv2.size() ? vv2[0] + len : 0ll), vv.back());
}
}
else if (l >= lcnt && r < rcnt) {
if (n == 11)
cout << 43 << endl;
vector<int> vv;
vector<int> vv2;
l-= lcnt;
for (int i= 1; i <= n; i++)
if (d[i])
vv2.push_back(len - a[i]);
for (int i= 1; i <= n; i++)
if (!d[i])
vv.push_back(a[i]以上是关于gym103117J. Ants的主要内容,如果未能解决你的问题,请参考以下文章