1. 程式人生 > >2016 計蒜之道 初賽 第一場

2016 計蒜之道 初賽 第一場

青雲的伺服器金鑰

題目連結:

https://nanti.jisuanke.com/t/11162

解題思路:

我們分類討論一下:

1、所有字母都沒有出現過:

直接輸出0即可。

2、只有一種字母:

這時,當字母數cnt>=2,對應的π值應該為cnt-1,比如 “aaaaa",π1=0,π2=1(a,a),π3=2(aa,aa(中間重合了一個a)),π4=3(123,

432(對應a的位置)),π2=4(aaaa,aaaa(表示的含義前面已經說了)),相加結果為10。

不難發現其中規律,是一個以1為首項,cnt-1為尾項的等差數列和。

aaa==3==1+2;

aaaa==6==1+2+3;

aaaaa==10==1+2+3+4;

3、兩種或者兩種以上的字母:

想要讓總和最小,那麼肯定想辦法讓他子序列重合的部分越少,因為子序列比較的位置是從1開始(這點是固定的),那麼我們就把

某個字母安排在這,它同種類的其他字母安排到最後,那麼前面不含這個字母的部分的π值都將為0,從開始出現這個字元,才有π

值,且只能為1,因為字尾只能和1號位置的匹配,這樣答案就應該是這個字母出現次數cnt-1。

AC程式碼:

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;

int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int x,cnt = 0;
        int ans = INF;
        for(int i = 0; i < 26; i++){
            scanf("%d",&x);
            if(x){
                ++cnt;
                ans = min(ans,x);
            }
        }
        if(cnt == 0){
            puts("0");
        }
        else if(cnt == 1){
            int sum = 0;
            for(int i = 1; i <= ans-1; ++i)
                sum += i;
            printf("%d\n",sum);
        }
        else
            printf("%d\n",ans-1);
    }
    return 0;
}