A.
题意:就是有一个大桌子,环绕有顺势站1~m共m个座位,n个选手坐在部分位置上。然后如果有一个人a了一道题,却没有立刻发气球给他,他产生怒气值是发气球给他的时间减去a题时间。现在有一个机器人顺时针环绕桌子发球,每个单位时间走过一个位置。问机器人在哪个位置开始发气球总怒气值最小,输出最小怒气值。
其实是个傻逼思维题。假如他从位置m开始发气球,对于每个位置i,他到达的时间为k*m+i,所以对于每个它在时刻t a的题,他需要等待t-(k*m+i)中最小的正整数时间。随便算算就能知道每一题从m位置开始具体产生的怒气值,从而算出怒气总值作为初始值(当然从其他位置也行)。然后他往逆时针移动一个位置开始,相当于所有a题时间在%m的意义下+1。因此我们从小到大排个序,从最后一个数字往第一个数字遍历一遍,每次的操作都是把该为数字加到0的数加到所有题上,算算总的怒气值,在这里面一定产生一个最小的怒气值。
1 #include<bits/stdc++.h> 2 #define clr(x) memset(x,0,sizeof(x)) 3 #define clr_1(x) memset(x,-1,sizeof(x)) 4 #define mod 1000000007 5 #define LL long long 6 using namespace std; 7 const int N=200010; 8 int n,m,q,k,T,u,v; 9 int pos[N],info[N]; 10 LL pp,qq,tt,ans,all; 11 int main() 12 { 13 scanf("%d",&T); 14 while(T--) 15 { 16 scanf("%d%d%d",&n,&m,&q); 17 for(int i=1;i<=n;i++) 18 { 19 scanf("%d",&pos[i]); 20 if(pos[i]==m) 21 pos[i]=0; 22 } 23 all=0; 24 for(int i=1;i<=q;i++) 25 { 26 scanf("%d%d",&u,&v); 27 v=v%m; 28 info[i]=(pos[u]-v+m)%m; 29 all+=info[i]; 30 } 31 n=q; 32 sort(info+1,info+n+1); 33 LL qq=0; 34 ans=all; 35 for(int i=n;i>=1;i--) 36 { 37 pp=m-(info[i]+qq); 38 all-=(LL)info[i]+qq; 39 all+=pp*(n-1); 40 qq+=pp; 41 if(all<ans) 42 ans=all; 43 } 44 printf("%lld ",ans); 45 } 46 return 0; 47 }