Problem Description
有一种纸牌游戏,很有意思,给你N张纸牌,一字排开,纸牌有正反两面,开始的纸牌可能是一种乱的状态(有些朝正,有些朝反),现在你需要整理这些纸牌。但是麻烦的是,每当你翻一张纸牌(由正翻到反,或者有反翻到正)时,他左右两张纸牌(最左边和最右边的纸牌,只会影响附近一张)也必须跟着翻动,现在给你一个乱的状态,问你能否把他们整理好,使得每张纸牌都正面朝上,如果可以,最少需要多少次操作。
Input
有多个case,每个case输入一行01符号串(长度不超过20),1表示反面朝上,0表示正面朝上。
Output
对于每组case,如果可以翻,输出最少需要翻动的次数,否则输出NO。
Sample Input
01 011
Sample Output
NO 1本题和那道一次只能翻相邻的两个硬币(2013年蓝桥杯的一道题)类似,直接模拟,不过那道题和这题不同的是那道题从开始到结束都是直翻两个,但本题在最左边和最右边可以只翻两个而最右边的翻法可以认为是翻了三次,因此只有把最左边翻或者不翻考虑一下就行了#include<stdio.h> #include<functional> #include<vector> #include<queue> #include<math.h> #include<cstring> #include<algorithm> #include<iostream> #define INF 9999999 using namespace std; int main() { string a,b,c; while(cin>>a) { int n=a.length(); b=a; c=a; int s=0; for(int i=0;i<n-1;i++)//最左边不翻两个 { if(a[i]=='1') { s++; a[i]='0'; if(a[i+1]=='0') a[i+1]='1'; else a[i+1]='0'; if(a[i+2]=='0') a[i+2]='1'; else a[i+2]='0'; } } int s1=0; if(b[0]=='0')//最左边翻两个 b[0]='1'; else b[0]='0'; if(b[1]=='0') b[1]='1'; else b[1]='0'; s1++; for(int i=0;i<n-1;i++) { if(b[i]=='1') { s1++; a[i]='0'; if(b[i+1]=='0') b[i+1]='1'; else b[i+1]='0'; if(b[i+2]=='0') b[i+2]='1'; else b[i+2]='0'; } } if(a[n-1]=='1'&&b[n-1]=='1') printf("NO\n"); else if(a[n-1]=='0'&&b[n-1]=='0') printf("%d\n",min(s,s1)); else if(a[n-1]=='1'&&b[n-1]=='0') printf("%d\n",s1); else printf("%d\n",s); } return 0; }
Problem Description
有一种纸牌游戏,很有意思,给你N张纸牌,一字排开,纸牌有正反两面,开始的纸牌可能是一种乱的状态(有些朝正,有些朝反),现在你需要整理这些纸牌。但是麻烦的是,每当你翻一张纸牌(由正翻到反,或者有反翻到正)时,他左右两张纸牌(最左边和最右边的纸牌,只会影响附近一张)也必须跟着翻动,现在给你一个乱的状态,问你能否把他们整理好,使得每张纸牌都正面朝上,如果可以,最少需要多少次操作。
Input
有多个case,每个case输入一行01符号串(长度不超过20),1表示反面朝上,0表示正面朝上。
Output
对于每组case,如果可以翻,输出最少需要翻动的次数,否则输出NO。
Sample Input
01 011
Sample Output
NO 1