题意:给出n个队伍,m个座位,q次A题的队伍与时间,下一行是n个队伍的坐的位置,再下面q行就是第x个队再第y秒A出一道题,然后有一个机器人,开始位置由你选,他每走一步
他就会向右走一格,走到m的时候会再次走到1位置,然后如果一个队在第x秒A出一道题,机器人第y秒才到,那么会有一个不开心值y-x,然后说你选一个位置,让不开心值最小
然后求这个不开心值是多少
思路:因为n的范围是1e5,m的范围是1e9,那我们肯定不可以暴力,我们想下,我们算出第一个位置的不开心值是多少,然后我们每推一个位置,其实就是每个减1,为负数的就要 (a+m)%m
那我们只要计算每次你移动多少个位置时有多少个为负数就行,
!!!枚举
我枚举哪个座位为0的时候的不开心值是多少,重点还是推出两个公式,详情看代码
#include<cstdio> #include<cstring> #include<stack> #include<algorithm> using namespace std; typedef long long ll; int main() { ll t,n,m,q; ll a[100001]; scanf("%lld",&t); while(t--) { scanf("%lld%lld%lld",&n,&m,&q); for(int i=0;i<n;i++) scanf("%lld",&a[i]); ll b[100001]; ll x,y; ll sum=0; for(int i=0;i<q;i++) { scanf("%lld%lld",&x,&y); b[i]=(m+a[x-1]-1-y%m)%m;//计算每个题的时间是多少 sum+=b[i]; } sort(b,b+q); ll mn=1e18; for(int i=0;i<q;i++) { if(i==0||b[i]!=b[i-1])//中间有一部分是一样的就不用计算 { mn=min(mn,sum-q*b[i]+i*m);//每移动一个位置就要-q,每个位置都要减1,然后我还要判断有多少个负数的情况,那些为负数的都要+m,所有我们事先排好了序,前面的都是为负数的 } } printf("%lld ",mn); } }