UESTC 490 Swap Game (特殊的求解逆序对数)

大体题意:
给你一个字符串,其中R表示红球,B 表示蓝球,其中字符串首尾相连。你可以交换任意相邻的球,问最少交换几次,使得红球在一边,蓝球在一边。
思路:
这个题目比赛没做出来,后来看的学长的博客补得题目。
  把RB想成1和0,换一个类似的简单题目来想,如果RB表示的字符串不是一个环,而是一条链的话,那么这个题目就是求逆序对数了,因为交换一次,最多交换一个逆序对,如果你的做法是最优的话,那么每一次交换都可以换一个逆序对,因此如果是一条链的话,那就是逆序对数量。
  这个题目需要变通一下,因为是一个环嘛,所以可以把左边的R变成1,B变成0,右边的R变成0,B变成1,这样两边分别求逆序对数,在相加,这就是其中一个答案,最优解答案,就是枚举所有的左右情况,求出最小的答案!

具体看代码 分析!


#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 100000 + 10;
char s[maxn];
int main(){
    int T,cnt = 0;
    scanf("%d",&T);
    while(T--){
        scanf("%s",s);
        int len = strlen(s);
        int posmid = len >> 1;//求出中间位置!
        int inver = 0;//表示从中间分为左右两侧的逆序对答案数!
        int tmp[2] = {}; // tmp[0]记录左边R(也就是1)的个数,tmp[1]记录右边B(也就是1)的个数。
        for (int i = 0; i < posmid; ++i){
            if (s[i] == 'R') ++tmp[0];
            else inver += tmp[0];
        }
        for (int i = posmid; i < len; ++i){
            if (s[i] == 'B')++tmp[1];
            else inver += tmp[1];
        }//以上两个循环,可以求得 从中间一分为二的逆序对数,和 左边1的个数和右边1的个数!
        int ans = inver;
        for (int i = 0; i < len; ++i){
            int t = (posmid + i) % len;  //  这样可以用s[t]表示右边的需要加入左边的字符,s[i]表示左边的需要加入右边的字符!
            if (s[t] == 'B'){
                inver += tmp[0] - (s[i] == 'R');
                inver -= (len-posmid-tmp[1]);
            }
            if (s[i] == 'R'){
                inver += tmp[1] - (s[t] == 'B');
                inver -= posmid-tmp[0];
            }// 以上两个判断  画一个样例图分析一下即可!
            if (s[i] == 'R')--tmp[0];
            else ++tmp[1];
            if (s[t] == 'B')--tmp[1];
            else ++tmp[0];// 移动完后 更新左右1的个数!
            ans = min(ans,inver);
        }
        printf("Case #%d: %d\n",++cnt,ans);

    }

    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值