2017 秦皇岛CCPC Balloon Robot (ZOJ 3981)

题意:给出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);
    }
}
原文地址:https://www.cnblogs.com/Lis-/p/9696541.html