广工校赛C.平分游戏(思维)

题目链接:https://www.nowcoder.com/acm/contest/90/C
思路:这道题很久之前在大白上写过差不多了,结果全忘了QAQ(很烦),这道题关键就是代数
分析的过程,其实做多这种也比较容易往代数分析上去想,这道题分析的时候有一个技巧,就是我们假定某个人只会给一个人银币(因为正负的关系其实是一样的),这样就会方便很多,然后
列出n个等式就会发现未知量只有一个,那么就是一维方向的极值问题,就是中位数,这道题稍微不一样的就是隔k个跳的,所以就是相当很多个圈,圈里的人是香玲者跳的,预处理出这些圈就行了
accode

#include<bits/stdc++.h>
#define LL long long
#define ULL unsigned long long
using namespace std;
const int maxn  =  1e6+65;
const LL mod = 998244353;
int n,k;
LL a[maxn];
vector<int>Q[maxn];
int vis[maxn];
int main()
{
    scanf("%d%d",&n,&k);
    LL tmpsum = 0;
    for(int i = 0;i<n;i++){
        scanf("%lld",&a[i]);
        tmpsum+=a[i];
    }
    if(tmpsum%n!=0){
        return 0*puts("gg");
    }
    tmpsum/=n;
    if(k==n){
        int falg  = 1;
        for(int i =0;i<n;i++){
            if(a[i]!=tmpsum) {falg = 0;break;}
        }
        if(!falg){
            return 0*puts("gg");
        }
    }
    int p = 0;
    for(int i = 0;i<n;i++){
        if(vis[i]) continue;
        int j = i;
        do
        {
            Q[p].push_back(j);
            vis[j] = 1;
            j = (j+k+1)%n;
        }while(!vis[j]);
        p++;
    }
    int falg = 1;
    for(int i = 0;i<p;i++){
        LL sum = 0;
        for(int j = 0;j<Q[i].size();j++){
            sum+=a[Q[i][j]];
        }
        if(sum%Q[i].size()!=0||sum/Q[i].size()!=tmpsum){
          //  cout<<i<<endl;
            falg = 0;
            break;
        }
    }
    if(!falg){
        return 0*puts("gg");
    }
    LL ans = 0;
    for(int i = 0;i<p;i++){
        vector<LL>c;
        LL tmp = 0;
        for(int j = 0;j<Q[i].size();j++){
            tmp += a[Q[i][j]]-tmpsum;
            c.push_back(tmp);
        }
        sort(c.begin(),c.end());
        for(int j = 0;j<c.size();j++){
            ans += abs(c[j]-c[c.size()/2]);
        }
    }
    printf("%lld\n",ans);
}

猜你喜欢

转载自blog.csdn.net/w571523631/article/details/79689161