确实是一道很好的题
(反正对我来说是的了)
在大概了解了(模糊的)思路之后
我就上手写了
纯模拟吧
每一轮就归排一次
当然时间复杂度是过不去的
(但是我是先wa的)
于是我才反思
得到了另半种种算法思路
如下:
根据题意
先把那一堆东西全输入进来
在根据初始的s值排序(这里是可以用sort的)
(这之前都很常规)
于是再循环每一轮
两两相比
把赢得放在一个数组,把输的放在一个数组
每个数组(赢输两数组)中都是降序的
在把这两个数组的每个头元素轮番比较放回原数组(和归并很类似,但比归并省了好多好多遍)
就odk了
省了好多呢
#include#include using namespace std; int n,r,q; int a[200100],win[200100],los[200100]; int s[200100],w[200100]; bool cmp(int x,int y) { if(s[x]==s[y]) return x s[y];} void sol() { int i,j; i=j=1,a[0]=0; while(i<=win[0] && j<=los[0]) if(cmp(win[i],los[j])) a[++a[0]]=win[i++]; else a[++a[0]]=los[j++]; while(i<=win[0]) a[++a[0]]=win[i++]; while(j<=los[0]) a[++a[0]]=los[j++]; } int main() { cin>>n>>r>>q;n*=2; for(int i=1;i<=n;i++) a[i]=i; for(int i=1;i<=n;i++) cin>>s[i]; for(int i=1;i<=n;i++) cin>>w[i]; sort(a+1,a+n+1,cmp); for(int i=1;i<=r;i++) { win[0]=los[0]=0; for(int j=1;j<=n;j+=2) if(w[a[j]]>w[a[j+1]]) { s[a[j]]++; win[++win[0]]=a[j]; los[++los[0]]=a[j+1]; } else { s[a[j+1]]++; win[++win[0]]=a[j+1]; los[++los[0]]=a[j]; } sol(); } cout<