翻紙牌遊戲(HDU-2209)

翻紙牌遊戲

Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3540    Accepted Submission(s): 1324


Problem Description
有一種紙牌遊戲,很有意思,給你N張紙牌,一字排開,紙牌有正反兩面,開始的紙牌可能是一種亂的狀態(有些朝正,有些朝反),現在你需要整理這些紙牌。但是麻煩的是,每當你翻一張紙牌(由正翻到反,或者有反翻到正)時,他左右兩張紙牌(最左邊和最右邊的紙牌,只會影響附近一張)也必須跟着翻動,現在給你一個亂的狀態,問你能否把他們整理好,使得每張紙牌都正面朝上,如果可以,最少需要多少次操作。
 

Input
有多個case,每個case輸入一行01符號串(長度不超過20),1表示反面朝上,0表示正面朝上。
 

Output
對於每組case,如果可以翻,輸出最少需要翻動的次數,否則輸出NO。
 

Sample Input
01 011
 

Sample Output
NO 1
解題思路:
       一開始用的廣搜但是因爲剪枝沒有處理好超時了,最後還是用了大神們的深搜(也不算是深搜啦尷尬)。。。。因爲題目說 每翻動 一張牌,左邊右邊的都要翻,所以從第二張牌開始,如果左邊的是“1”,就把中、左、右都翻一下,一直到最後一張,翻到最後如果最後一張是“0”那就成功了,不然就是失敗了,對於第一張牌,它左邊沒有牌,所以分成兩種情況,即翻或不翻。注意:若兩種情況都可行取最小者。
代碼如下:
#include<stdio.h>
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
string sh;
int len,answer_1,answer_2;
int dfs(string s,int sum);
int main()
{
	while(cin>>sh)
	{
		len = sh.length();
		answer_1 = dfs(sh,0);
		sh[0]=(sh[0]=='0')?'1':'0';
		sh[1]=(sh[1]=='0')?'1':'0';
		answer_2 = dfs(sh,1);
		if(answer_1+answer_2==-2) printf("NO\n"); 
		else if(answer_1!=-1 && answer_2!=-1) printf("%d\n",min(answer_1,answer_2)); 
		else printf("%d\n",answer_1==-1?answer_2:answer_1);
	}
	return 0;
}
int dfs(string s,int sum)
{
	for(int i=1 ; i<len ; i++)
	{
		if(s[i-1]=='0')continue;
		sum++;
		s[i] = (s[i]=='0')?'1':'0';
		s[i-1] = (s[i-1]=='0')?'1':'0';
		if(i+1<len)
		s[i+1] = (s[i+1]=='0')?'1':'0';
	}
	if(s[len-1]=='1') return -1;
	return sum;
}

題目傳送門............
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章