廣工校賽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);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章