闲暇时间,做了一道Codeforces试题,上图
大致意思:Anatoly有一列胡乱排序的r 和 b ,他是完美主义者,他想要通过一些操作,将这些r和b按照 1212121...的方式排列。
这个强迫症先生有两种方式:
In one turn he can either swap any two cockroaches, or take any single cockroach and change it's color.
即可以交换队列中的任意两个,也可以对任意的单个进行染色(其实,r指red,b指black)
问:任何的操作都算一次,最少几次达到目标?
我的大概思路是:
这种题我会先用人脑计算几个例子,我发现人脑总是能很快“巧妙“的找到答案,这并不利于计算机语言。如果每一步操作都试着用两种方式来解决,看哪个好,也许可以动态规划来解决,但是好像并不是那样,因为两种方式一种是对两个数操作,一种是对一个数操作。那该怎么办....我建议如果有人看到这的话,可以试着思考5分钟。
有些时候,宏观思考会让问题变得简单。我发现两个特点:1、只要第一个确定,后面的必须按1212121的方式,就都会确定。2、两个数交换的方式比对单个数染色的方式更“好”。
于是,我有了自己的算法。
于是我的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Codeforces9_AnatolyAndCockroaches {
class Program {
static void Main( string[] args ) {
//In one turn he can either swap any two cockroaches, or take any single cockroach and change it's color.
int charsLength = int.Parse( Console.ReadLine() );
string inputValue = Console.ReadLine();
char[] chars = inputValue.ToCharArray();
if ( chars.Length != charsLength ) {
InputWrong();
return;
}
Console.WriteLine( Math.Min( GetTurnCount( 'r', chars ), GetTurnCount( 'b', chars ) ) );
Console.Read();
}
private static int GetTurnCount( char headChar, char[] chars ) {
int rCount = 0;
int bCount = 0;
char temp = headChar;
for ( int i = 0; i < chars.Length; ++i ) {
if ( chars[i] != temp ) {
if ( temp == 'r' ) rCount++;
else bCount++;
}
temp = temp == 'r' ? 'b' : 'r';
}
return rCount > bCount ? rCount : bCount;
}
private static void InputWrong() {
Console.WriteLine( "input wrong!" );
Console.Read();
}
}
}
在GetTurnCount方法中,temp是一个辅助变量,我觉得这里可以进行优化,因为判断奇偶性就可以干这个事。
于是我将GetTurnCount方法改成:
private static int GetTurnCount( char headChar, char[] chars ) {
int rCount = 0;
int bCount = 0;
for ( int i = 0; i < chars.Length; ++i ) {
if ( chars[i] != ( i % 2 == 0 ? headChar : ( headChar == 'r' ? 'b' : 'r' ) ) ) {
if ( chars[i] == 'r' ) rCount++;
else bCount++;
}
}
return rCount > bCount ? rCount : bCount;
}
但是,当我将这段代码给别人看的时候。他们的第一反应是,看不懂!这两段代码是表达一个意思么?
正当我以为节省了一个变量而沾沾自喜的时候,他们告诉我其实(i%2)也要占用一个int空间。其实就是没省,反而代码难以阅读了。
我勒个去....我马上去查了一下:什么是“好”的代码。