【CF625E】Frog Fights(模擬)
阿新 • • 發佈:2018-07-02
etc puts 更新 題解 reg read efi 數量 它的 裏面去。
每次顯然是把時間最小的那次淘汰給從\(set\)中取出來,
淘汰對應的青蛙,並且更新一下狀態就好了。
【CF625E】Frog Fights(模擬)
題面
CF
洛谷
翻譯:
有\(n\)只青蛙在一個被分為了\(m\)等分的圓上,對於每份順時針依次標號。
初始時每只青蛙所在的位置是\(p_i\),速度是\(a_i\)。
然後從\(1\)號青蛙開始,順次移動,每只青蛙順時針移動\(a_i\)個格子。
途中碰到的所有青蛙都會被他淘汰。
如果它淘汰了\(x\)只青蛙,那麽它的速度會變為\(a_i-x\)
求最終剩下的青蛙數量以及編號。
題解
發現在沒有淘汰的情況下,所有青蛙的相對位置是不會發生變化的。
那麽,我們按照所有青蛙所在的位置依次排序,計算一下它淘汰前面那只青蛙的時間。
把所有的這個時間全部丟到\(set\)
每次顯然是把時間最小的那次淘汰給從\(set\)中取出來,
淘汰對應的青蛙,並且更新一下狀態就好了。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<set> #include<map> #include<vector> #include<queue> using namespace std; #define ll long long #define RG register #define MAX 111111 #define inf 1e9 inline int read() { RG int x=0,t=1;RG char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')t=-1,ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar(); return x*t; } int p[MAX],a[MAX],n,m,q[MAX],nt[MAX],lt[MAX]; set<pair<int,int> >S; bool cmp(int a,int b){return p[a]<p[b];} int calc(int x,int y) { if(x==y)return inf; int d=(p[y]-p[x]+m)%m; if(y<x)d=(d+a[y])%m; if(d<=a[x])return 1; if(a[x]<=a[y])return inf; return (d-a[y]-1)/(a[x]-a[y])+1; } int main() { n=read();m=read(); for(int i=1;i<=n;++i)p[i]=read()-1,a[i]=read(),q[i]=i; sort(&q[1],&q[n+1],cmp); for(int i=1;i<=n;++i)nt[q[i]]=q[i+1],lt[q[i]]=q[i-1]; nt[q[n]]=q[1];lt[q[1]]=q[n]; for(int i=1;i<=n;++i)S.insert(make_pair(calc(i,nt[i]),i)); while(233) { pair<int,int> u=*S.begin();if(u.first==inf)break; int v=u.second;S.erase(S.begin()); S.erase(make_pair(calc(nt[v],nt[nt[v]]),nt[v])); if(!S.empty())S.erase(make_pair(calc(lt[v],v),lt[v])); p[v]+=u.first;p[v]%=m;--a[v]; nt[v]=nt[nt[v]];lt[nt[v]]=v; S.insert(make_pair(calc(lt[v],v),lt[v])); S.insert(make_pair(calc(v,nt[v]),v)); } printf("%d\n",S.size()); for(set<pair<int,int> >::iterator it=S.begin();it!=S.end();++it)printf("%d ",it->second); puts("");return 0; }
【CF625E】Frog Fights(模擬)