CDOJ 490 UESTC 490 Swap Game

题意:有两种颜色的小球形成环,求最小交互次数使球相连。

题解:先解决另一个简单的问题,如果是一个链,把红球标记为1,蓝球标记为0,要排成升序需要多少次交换呢?答案是逆序对总数,原因是一次交互最多消除一个逆序对,而且有策略可以保证每次消除一个逆序对。要解决这个问题,需要做一些变通。看蓝球,因为是环,为了使交换次数最小,前半段的蓝球应该往前靠,所以在后半段的蓝球应该往后靠。那么就把原序列划分成两半,前面一段记红球为1,蓝球为0,后面一段记蓝球为1,红球为0,然后分别计算逆序对数,就可以求出以0位置前为中心的逆序数。然后在枚举中心的位置,枚举的时候,可以在O(1)时间计算出新的逆序值,具体方法是只考虑端点处的小球对左右区间逆序值的影响。

记左区间长度为b1,把中心移动到b1+i球的后面,那么b1+i位置的球会加入左区间,i号球则加入到右区间,当b1+i号球是R的时候,它对左右两边的逆序值都是没有影响的,(对于右区间,R是0,对于左区间,R是1),当它是B的时候,对于右区间,逆序对总数减少了原来右区间中0的个数,对于左区间,增加了i移动之后1的个数。对于i的移动,类似地讨论一下。

#include<cstdio>
#include<cmath>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
//#define local

const int maxn = 1e5+500;

int C[2];

char str[maxn];

int main()
{
#ifdef local
    freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
#endif // local
    int T;
    scanf("%d",&T);getchar();
    for(int k = 1; k <= T; k++){
        printf("Case #%d: ",k);
        gets(str);
        memset(C,0,sizeof(C));
        int len = strlen(str);
        int invSum  = 0;
        int b1 = len>>1,b2 = len - b1;
        for(int i = 0; i < b1; i++) {
            if(str[i] == ‘R‘) { C[0]++;}
            else { invSum += C[0]; }
        }
        for(int i = b1; i < len; i++) {
            if(str[i] == ‘B‘) {  C[1]++;}
            else { invSum += C[1]; }
        }

        int best = invSum;
        //printf("%d\n",best);
        for(int i = 0; i < len; i++){
            int t = (b1+i)%len;
            if(str[t] == ‘B‘) { invSum -= b2-C[1]; invSum += C[0]- (str[i] == ‘R‘); }
            if(str[i] == ‘R‘ ) { invSum -= b1-C[0]; invSum += C[1] - (str[t] == ‘B‘); }
            if(str[t] == ‘B‘) C[1]--;
            else C[0]++;
            if(str[i] == ‘R‘) C[0]--;
            else C[1]++;
            best = min(invSum,best);
        }
        printf("%d\n",best);
    }
    return 0;
}
时间: 2024-10-11 21:53:19

CDOJ 490 UESTC 490 Swap Game的相关文章

CDOJ 485 UESTC 485 Game

题意:八数码,但是转移的方式是转动,一共十二种,有多组询问,初态唯一,终态不唯一. 题解:初态唯一,那么可以预处理出012345678的所有转移情况,然后将初态对012345678做一个映射,再枚举一下终态的所有情况,取最小值即可. 不得不学了逆cantor展开,cantor展开是一个变进制数,每位上是原序列对应位置上的逆序值.那么求逆时候,就先除最大的位权得到对应位置上的逆序值,根据逆序值可以知道他在原序列中第几大,然后标记它,迭代.状态转移有点烦.一开始还担心超时,就打了个表直接存到程序里,

记一次生产数据库&quot;意外&quot;重启的经历

前言 在一个阳光明媚的下午,电脑右下角传来一片片邮件提醒,同时伴随着微信钉钉的震动,打开一看,应用各种出错,天兔告警,数据库服务器内存爆红,Mysql数据库实例挂掉了. 排查 先交代一下数据库版本: mysql> status -------------- mysql Ver 14.14 Distrib 5.7.22-22, for Linux (x86_64) using 6.2 Connection id: 59568 Current database: Current user: root

hightmaps 按地图显示统计量

从extjs 到 easyui 到html5到hightchars 再到hightmaps.Exjts和easyui很相似,extjs是重量级的,easyui轻量级的,比extjs容易上手,照着demo改就可以开发了,easyui入门demo见:easyui-demo,或者到官网http://www.jeasyui.com/:会了easyui开发,上手html5界面开发也非常的快,大多类似的,到html5-demo界面开发 下载demo 然后把demo放到自己的web项目中或者访问http://

基于WinDbg的内存泄漏分析

在前面C++中基于Crt的内存泄漏检测一 文中提到的方法已经可以解决我们的大部分内存泄露问题了,但是该方法是有前提的,那就是一定要有源代码,而且还只能是Debug版本调试模式下.实际上很 多时候我们的程序会用到第三方没有源代码的模块,有些情况下我们甚至怀疑系统模块有内存泄露,但是有没有证据,我们该怎么办? 这时我们就要依靠无所不能的WinDbg了. WinDbg的!heap命令非常强大,结合AppVerifier可以对堆(heap)内存进行详细的跟踪和分析, 我们接下来对下面的代码进行内存泄漏的

中国地图 xaml Canvas

<Canvas x:Name="LayoutRoot"  Height="560" Width="700" Background="Transparent">       <Canvas  x:Name="CanvasPolygon">         <Polygon Fill="#FFE9800B" IsHitTestVisible="True

思路很重要!不同厂商Spanning-tree对接案例思考

朋友们是否经历过客户网络设备替换割接,如果被替换的设备和新设备不是一个厂商,往往在割接准备过程中会暴露出很多棘手的问题.例如,设备厂商往往有大量的私有协议,从而导致了在不同厂商设备之间无法正常互联互通.如果碰到这种情况你会怎么做? 我想无外乎以下两种种可能性: 修改新设备网络设计方案,针对目前旧设备做出妥协,从而避免私有协议带来的网络故障问题. 寻找一个共通的标准协议,并把老设备的协议逐步替换成业界标准协议.完成以后再准备替换工作. 但是两个方案都不是最优方案 方案一虽然实施起来相对容易,缩短工

SVG:中国地图

中国地图 <svg height="578" version="1.1" width="718" xmlns="http://www.w3.org/2000/svg" style="overflow: hidden; position: relative;"><desc style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);&q

在ros-kinetic与gazebo仿真环境下给turtlebot配置hokuyo激光雷达

背景 由于我之前按照百度上博客教程给gazebo上的turtlebot配置rplidar的时候一直失败,后来发现是因为在ros-indigo和kinetic下的一些差异导致配置失败,于是又搜了一些教程成功配置了hokuyo的激光雷达,并且能够较完美地运行,感觉比较激动,所以想写个教程避免自己以后再次踩坑. 准备 安装好ros-turtlebot以及ros-turtlebot-apps,可以选择源码安装或者apt安装 增加hokuyo模块 ( 如果是使用apt安装的apps,首先需要  sudo

python跳一跳辅助学习

微信跳一跳辅助工具 准备工具 adb驱动 安卓手机 打开手机的调试模式 usb接好手机和电脑 PyCharm:全宇宙唯一一款专门用于Python开发IDE工具 实现原理: 获取手机的实时的截图 点击起始位置和落地位置 技算两个点的距离 计算按压时间 发送按压指令 重新刷新手机截图 实现代码: import os import PIL,numpy import matplotlib.pylab as plt from matplotlib.animation import FuncAnimatio