问题描述:

Given a string consisting of a,b and c's, we can perform the following operation: Take any two adjacent distinct characters and replace it with the third character. For example, if 'a' and 'c' are adjacent, they can replaced with 'b'. What is the smallest string which can result by applying this operation repeatedly?

翻译:

给定一个由a/b/c构成的字符串,你可以把相邻且不同的两个字符替换为剩下的那一个字符,比如你可以把字符串中的‘ab’替换为‘c’。求通过不断的替换操作,最后能得到的字符串的最小长度是多少?

Sample Input


cab 
bcab 
ccccc

Sample Output



5

样例解释:

cab -> cc or cab -> bb

bcab -> aab -> ac -> b

ccccc 不可变


解答

令X Y Z分别代表'a' 'b' 'c'中的一个字符(三个字符等价,我们只关心不同字符排列的关系)。

令S为给定的字符串,|X| |Y| |Z| |S| 分别为 X Y Z 的个数和 S 的长度。

有以下几种情况:

1. S只含1种字符,此时字符串不可被归约,答案即|S|.

2. S含2种字符,X 和 Y. 那么又有以下几种情况:

  (1) |S| = 2

  S 为 XY 或 YX,两种情况都可以归约为Z,答案为1.

  (2) |S| = 3

  假设|X| = 2,|Y| = 1. S 有3种情况:XYX YXX XXY 这3种情况都可以归约为Y,答案为1.

  (3) |S| > 3

  从|S| = 3 的情况我们知道XYX YXX XXY都可以归约为Y,并且不会引入Z. 所以,我们可以对S按以下步骤不断归约:

    i  找出|X|和|Y|中较小者(或相等),假设为Y (|Y| <= |X|)

    ii  我们从S中至少可以找到1个Y周围是这样的形式:XXY, XYX 或 YXX. (因为如果找不到,那么要么|X|=|Y|=1, 要么|Y| > |X|,与前面的前提矛盾)。将这个子串替换为Y.

    iii  如果 |S| > 3,转到 i.

  在 ii 中,字符长度每次减少2. 减少的是2个当前数目较多那一类字符(X)。

  假设|S|是奇数:那么每次减少2个字符最后会剩余1个字符,所以答案是1.

  假设|S|是偶数:那么最后剩余2个字符,一种情况剩余两个字符不同,那么答案是1,另一种情况剩余两个字符相同,那么答案是2。

  那么|S|是偶数时,如何确定剩余的字符是否相同?从 ii 中看到每次归约中字符都是2个一起被去掉。所以当|S|为偶数时,有两种情况:

    |X|为偶,|Y|也为偶,这样最后留下的是两个一样的字符,答案为2.

    |X|为奇,|Y|也为奇,这样最后留下的是两个不同的字符,答案为1.

  加上前面的情况:

  |S| = 2,|X| = |Y| = 1 均为奇数,答案为1.

  |S| = 3,|X| = 2为偶, |Y| = 1为奇

  所以S仅由两种字符构成的情况下的结论为:如果|X|和|Y|都是偶数那么答案是2,否则为1.

3. S由3种字符构成

归约方法:

  (1) 找到数目最小的字符Z;

  (2) 找到一个与X(Y)相邻的Z,将它们替换为Y(X);

  (3) 如果|Z| > 0,转(2).

通过不断这样的操作可以消除所有的Z,从而得到只由两个字符组成的串,退化到第2种情况。

第(2)步中每次|Z|减少1,同时带走一个X或Y,同时引入一个新的Y或Z.

设|Rx| |Ry|为被带走的X和Y的数量,|Ix| |Iy|为引入的X和Y的数量,|Ox| |Oy|是原始字符串中X和Y的数目, |X|和|Y|为消去Z之后的串中X和Y的数目。则有以下关系:

  |Rx| + |Ry| = |Z|

  |Rx| =|Iy|        |Ry| = |Ix|

  |X| = |Ox| + |Ix| - |Rx| = |Ox| + (|Ry| - |Rx|)

  |Y| = |Oy| + |Iy| - |Ry| = |Oy| + (|Rx| - |Ry|)

再分两种情况讨论:

  |Z| 为奇数:|Rx| |Ry|一定是一奇一偶。假设|Rx|为奇,|Ry|为偶,那么|Ry| - |Rx| 和 |Rx| - |Ry|都是奇数。所以如果|Ox|和|Oy|都是奇数,那么|X|和|Y|都是偶数,按前面的结论知答案为2;如果|Ox|和|Oy|至少1个偶数,那么答案为1。

  |Z|为偶数:|Rx| |Ry|要么都奇,要么都偶。无论是奇是偶,|Rx| - |Ry| 和 |Ry| - |Rx| 都一定是偶数。所以若|Ox||Oy|都为偶数,那么|X|和|Y为也都为偶数,答案为2;若|Ox| |Oy|中至少1个奇数,那么答案为1.

例外情况:如果只有1个Z和1个X,而且它们恰好相邻:

  ZXYY...  ...YYZXYY...    ...YYXZ

此时不应该将ZX归约为Y,而应该将XY归约为Z.

结论:归约后最终剩余字符个数只与原字符串中各个字符的奇偶性有关。

|X|==|S| && |Y|==0 && |Z| ==0,                                         answer = |S|;

|X|, |Y|, |Z| 都为奇数或都为偶数,                                             answer =   2 ;

|X|, |Y|, |Z| 中既有奇数又有偶数,                           answer =   1 ;

所以求这个问题只需要扫描一次串,统计各种元素的个数即可,代码就不贴了。

String Reduction问题分析的更多相关文章

  1. java基础解析系列(九)---String不可变性分析

    java基础解析系列(九)---String不可变性分析 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系列(二)---In ...

  2. String类原理分析及部分方法

    //String类原理分析及部分方法 //http://www.cnblogs.com/vamei/archive/2013/04/08/3000914.html //http://www.cnblo ...

  3. String对象内存分析

    Java中内存分析: 栈(Stack) :存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放在常量池中). 堆(heap): ...

  4. (转)Java中的String为什么是不可变的? -- String源码分析

    背景:被问到很基础的知识点  string  自己答的很模糊 Java中的String为什么是不可变的? -- String源码分析 ps:最好去阅读原文 Java中的String为什么是不可变的 什 ...

  5. 【转载】常见面试题:C#中String和string的区别分析

    在很多人面试C#开发工程师的时候,会遇到一个面试题,就是C#中String和string有啥区别.其实针对这个问题C#中String和string没有本质上的区别,两者在程序中都可使用,稍微的一个区别 ...

  6. String reduction (poj 3401

    String reduction Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1360   Accepted: 447 D ...

  7. String Reduction

    问题出自这里 问题描述: Given a string consisting of a,b and c's, we can perform the following operation: Take ...

  8. string源码分析 ——转载 http://blogs.360.cn/360cloud/2012/11/26/linux-gcc-stl-string-in-depth/

    1. 问题提出 最近在我们的项目当中,出现了两次与使用string相关的问题. 1.1. 问题1:新代码引入的Bug 前一段时间有一个老项目来一个新需求,我们新增了一些代码逻辑来处理这个新需求.测试阶 ...

  9. java string 细节原理分析(2016.5)

    看到了以前2016.5月学习java写的笔记,这里放在一起. String实现的细节原理分析 一.jdk源码中String 的实现 public final class String implemen ...

随机推荐

  1. Jquery缩放

    $(document).mousemove(function(e) {     if (!!this.move) {         var posix = !document.move_target ...

  2. Nginx Rewrite研究笔记

    原文出自:http://blog.cafeneko.info/2010/10/nginx_rewrite_note/ 在新主机的迁移过程中,最大的困难就是WP permalink rewrite的设置 ...

  3. 刷题向》POJ2823 单调队列裸题(<不会做,请自裁>系列)

    最近BZOJ炸了,而我的博客上又更新了一些基本知识,所以这里刷一些裸题,用以丰富知识性博客 POJ2823   滑动的窗口 这是一道经典的单调队题,我记得我刚学的时候就是用这道题作为单调队列的例题,算 ...

  4. SHELL读取 ini 格式文件做配置文件

    ini文件格式一般都是由节.键.值三部分组成 格式: [第一节 ] 第一个键 = 值 第二个键 = 第二个值 [第二节 ] 第一个键 = val1,val2,val3 例子: [COM] KINGGO ...

  5. Apache rotatelogs命令

    一.简介 rotatelogs 是 Apache 自带的管道日志程序,可以完美的实现日志的轮转功能. 二.语法 Usage: rotatelogs [-v] [-l] [-L linkname] [- ...

  6. zynq qemu学习

    1,ubuntu给软件包降级,先安装aptitude sudo apt-get  install aptitude 2,强制降级,等号“=”前后不能有空格 sudo aptitude install ...

  7. 39.FORMAT() 函数

    FORMAT() 函数 FORMAT 函数用于对字段的显示进行格式化. SQL FORMAT() 语法 SELECT FORMAT(column_name,format) FROM table_nam ...

  8. 几种导入osm(openstreetmap)数据的方法

    一osm2pgsql+postgresql+postgis osm2pgsql­——是由OpenStreetMap开发的一个命令行工具负责将OSM数据导入到基于PostgresSql的Postgis的 ...

  9. PC/APP/H5三端测试的相同与不同

    随着手机应用的不断状态,同一款产品的移动端应用市场占相较PC端也越来越大,那么app与PC端针对这些产品的测试有什么相同与不同之处呢?总结如下: 首先谈一谈相同之处: 一,针对同一个系统功能的测试,三 ...

  10. GCC 4.7相对4.6.x的改进点

    原文:http://www.iteye.com/news/24628针对C的功能改进: 支持ISO C11标准中的更多特性.除了之前的-std=c1x和-std=gnu1x选项外,GCC现在还支持-s ...