翻纸牌 高校俱乐部 英雄会 csdn

时间:2023-03-09 19:10:37
翻纸牌 高校俱乐部 英雄会 csdn

题目描述 有一种纸牌游戏,很有意思,给你N张纸牌,一字排开,纸牌有正反两面,开始的纸牌可能是一种乱的状态(有些朝正,有些朝反),现在你需要整理这些纸牌。但是麻烦的是,每当你翻一张纸牌(由正翻到反,或者有反翻到正)时,他左右两张纸牌(最左边和最右边的纸牌,只会影响附近一张)也必须跟着翻动,现在给你一个乱的状态,问你能否把他们整理好,使得每张纸牌都正面朝上,如果可以,最少需要多少次操作。
输入 有多个case,每个case输入一行01符号串(长度不超过20),1表示反面朝上,0表示正面朝上。 输出 对于每组case,如果可以翻,输出最少需要翻动的次数,否则输出NO。

两星的题目,其实说真的,这题目蛮有意思的,不过贪心算法完美解决。

首先要分支:

人为操作:第一个翻,第一个不翻。(可以同一个空间两次读入,我是开了两个空间……)

之后从i=1开始读起,看i-1是否为1,是的话,就翻动,ans1++,直到len-2,而如果len-1为1,那么ans1=inf

同理对于不人为翻动的执行上数操作,得到ans2.

之后最后的结果就是ans=min(ans1,ans2),如果ans==MAX,那么结果为NO。

来考虑一下,为什么是对的?

在一个翻动的操作中,除了第0位和第len-1位是影响两个,其余均为影响左中右,也就是掀牌的时候,如果看到“中”要翻动,那么“左”本来是好的,则会被干扰,我们可以从为此,我们在保证i步后不需要考虑已经走过的地方,那么我们需要只影响乱序(也就是在左是乱的时候,中就翻)。

其实可以考虑成一个数组

011000101

最后通过加1,直到每一个数都为偶数……要打球了。。晚点再更新。。。

.

/*******************************************************************************/
/* OS : 3.2.0-58-generic #88-Ubuntu SMP Tue Dec 3 UTC 2013 GNU/Linux
* Compiler : g++ (GCC) 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
* Encoding : UTF8
* Date : 2014-03-18
* All Rights Reserved by yaolong.
*****************************************************************************/
/* Description: ***************************************************************
*****************************************************************************/
/* Analysis: ******************************************************************
*****************************************************************************/
/*****************************************************************************/ #include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define MAX 1<<30
int a[30],b[30];
char str[30]; int main(){
int i,len,ans,ans1,ans2;
while(~scanf("%s",str)){
len=strlen(str);
for(i=0;i<len;i++){
a[i]=b[i]=str[i]-'0';
}
a[0]=!a[0];
a[1]=!a[1];
ans1=1;ans2=0;
for(i=1;i<len;i++)
{
if(a[i-1]){
ans1++;
a[i-1]=!a[i-1];
a[i]=!a[i];
a[i+1]=!a[i+1];
} }
if(a[len-1]){ans1=MAX;} for(i=1;i<len;i++)
{
if(b[i-1]){
ans2++;
b[i-1]=!b[i-1];
b[i]=!b[i];
b[i+1]=!b[i+1];
} }
if(b[len-1]){ans2=MAX;}
ans=ans1>ans2?ans2:ans1;
if(ans==MAX) printf("NO\n");
else printf("%d\n",ans); }; return 0;
}