Codeforces Round #581 (Div. 2) 重點:C.Anna, Svyatoslav and Maps

啥也不多說了,重拾堅持題解,不寫題解不是人,做一題寫一題,不轉不是中國人(最後一句純玩梗,瓜衆散了散了
題目鏈接:在這裏

A.BowWow and the Timetable

題意:快A題,主要是注意審題

int main(){
    string a;
    while(cin >>a){
        int f = 0;
        for(int i = SZ(a)-1;i >=1 ;i --){
            if(a[i]=='1')f = 1;
        }
        if(SZ(a)%2 == 1){
            if(f)cout<<SZ(a)/2+1<<endl;
            else cout<<SZ(a)/2<<endl;
        }
        else{
            cout<<SZ(a)/2<<endl;
        }
    }
}

B. Mislove Has Lost an Array

題意:構造1 2 4 8…l和r個不同的數,讓你找和最小與最大值
思路:如題意

int main()
{
    int n,l,r;
    cin>>n>>l>>r;
    int sum1=1,sum2=1;
    for(int i=1;i<=l-1;i++) {
        sum1+=(1<<i);
    }
    sum1+=(n-l);
    for(int i=1;i<=r-1;i++) {
        sum2+=(1<<i);
    }
    sum2+=(n-r)*(1<<(r-1));
    cout<<sum1<<" "<<sum2<<endl;
    return 0;
}

C.Anna, Svyatoslav and Maps

本次的重點題,wa了無數次還不過的;
題意:題意確實有點小難懂,結合樣例,我們可以看出首先就是給你一個圖的二維表,和一個p序列,你需要構造一個長度最短的v序列,他要滿足是p序列的子序列(subsequence)並且你按照v走並不會改變p的行走順序,第一個樣例非常典型。

廢話:這裏的題解思路是陽關大道式的解法,當然也是本題的標程,這裏先說說標程,這是後來我才學會的,剛開始的貪心屬實是貪懵了,貪了快一個半小時了,cf題真的,找不到正解就是這樣的,我還沒有徹底懂得及時換思路的重要性,我弱啊,找不到/dk。

思路:首先是Floyd將任意兩個聯通點的最短距離給算出來
不連通那麼我們就inf,另外一定要注意將與自身自環的點的距離初始化爲0,這點真的很重要,開頭的點一定要加入答案的數組當中,那接下來我們怎麼維護呢?我們剛開始的有一點思路一定是這樣,我們先這樣想因爲對於每連續的三個點假設爲k1,k2,k3來說,如果,k1 和 k3直接存在一條通路的話,那麼k2這個點一定是不能被省略掉的,也就是說k2這個點必須要被加入到v數組裏面,否則k1,k3直接相連便會改變原序列的行走順序,那麼既然這樣的話,對於每一個上一次被加入到序列裏的點,和當前的點在p序列裏面的距離如果小於等於他們的最短距離了,那我們是不是可以不動,反過來,如果大於他們的最短距離了,那麼我們就要把pi-1加入答案數組了,放i-1大家應該能想明白把,因爲放i的話就改變了呀,現在考慮我們最初的一件事,就是當上一次被放入隊列中的點和當前的點相同了怎麼辦,走回原點了?這時候我們的mp[i][i]=0就起到作用了,因爲雖然沒有自環,但出現連續兩個相同的值顯然是不合理的,而那樣的初始化就可以保證了自環距離更小,會被加入v數組,好了本題就完成了。良心寫題解,還有自己的hack樣例!

int n,m;
char a[110][110];
int mp[110][110];
int p[N];
int main(){
    while(~scanf("%d",&n)){
        for(int i = 1; i <= n ; i ++){
            scanf("%s",a[i] + 1);
        }
        for(int i = 1;i <= n;i ++){
            for(int j = 1; j <= n;j ++){
                if(a[i][j]=='1')mp[i][j]=1;
                else mp[i][j]=inf;
            }
            mp[i][i]=0;
        }
        for(int i = 1 ; i <= n ; i ++){
            for(int j = 1 ; j <= n ; j ++){
                for(int k = 1 ; k <= n ; k ++){
                    mp[i][j] = min(mp[i][j],mp[i][k] + mp[k][j]);
                }
            }
        }
        scanf("%d",&m);
        for(int i = 1; i <= m ; i ++){
            scanf("%d",&p[i]);
        }
        VI v;
        v.pb(p[1]);
//        set<int>s;
        int last = p[1],res = 1;
        for(int i =2; i <= m; i ++){
            if(mp[last][p[i]] < i - res ){
                v.pb(p[i-1]);
                last = p[i-1];
                res = i - 1;
            }
        }
        v.pb(p[m]);
        printf("%d\n",SZ(v));
        for(auto x:v){
            printf("%d ",x);
        }puts("");

    }

}
/***
4
0101
0010
1000
0000
5
1 2 3 1 4
5
01000
00100
00010
00001
00000
5
1 2 3 4 5
****/

D2.Kirk and a Binary String (hard version)

佔坑待補

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章