Stay Hungry,Stay Foolish!

C - One Time Swap

C - One Time Swap

https://atcoder.jp/contests/abc345/tasks/abc345_c

 

思路

组合计数,

假设字符串中所有位置的字符都不相同,求所有位置字符交换的组合数

对于相同字符的位置, 任意两个位置交换不会改变字符串

所以计算所有这种无效贡献

注意最后对所有的无效贡献,需要保留一个,对应唯一的一个字符串

https://zenn.dev/testcampus/articles/d8f6f4cc760fa0

 

Code

string s;

int main()
{
    cin >>s;
    
    long long len = s.size();
    
    long long combtotal = (len*(len-1)) >> 1;
    
//    cout << "combtotal=" << combtotal << endl;
    
    long long cnt[26] = {0};

    bool duplicate = false;
    for(char one: s){
        cnt[one-'a']++;
        
        if (cnt[one-'a']>1){
            duplicate = true;
        }
    }

    long long combduplicate = 0;
    for(int i=0; i<26; i++){
        if (cnt[i] <=1){
            continue;
        }
        
        long long charcnt = cnt[i];
        long long combone = (charcnt*(charcnt-1)) >> 1;
        /*
        should not minus one here,
        because if two or more chars appears twice or more,
        even though every switch of one char only contribute once
        
        for example
        aa b cc
        aa switch and cc switch only count once.
        
        so every char counts 1 switch
        combduplicate = 2
        but you need to keep one after counting all chars
        
        combduplicate - 1
        */
//        combone--;
        
        combduplicate += combone;
    }

//    cout << "combduplicate=" << combduplicate << endl;

    if (!duplicate){
        cout << combtotal << endl;
    } else {
        long long ans = combtotal - (combduplicate - 1);
        
        cout << ans << endl;
    }

    return 0;
}

 

posted @ 2024-03-18 08:49  lightsong  阅读(15)  评论(0编辑  收藏  举报
Life Is Short, We Need Ship To Travel