翻纸牌游戏
Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1720 Accepted Submission(s): 582
Problem Description
有一种纸牌游戏,很有意思,给你N张纸牌,一字排开,纸牌有正反两面,开始的纸牌可能是一种乱的状态(有些朝正,有些朝反),现在你需要整理这些纸牌。但是麻烦的是,每当你翻一张纸牌(由正翻到反,或者有反翻到正)时,他左右两张纸牌(最左边和最右边的纸牌,只会影响附近一张)也必须跟着翻动,现在给你一个乱的状态,问你能否把他们整理好,使得每张纸牌都正面朝上,如果可以,最少需要多少次操作。
Input
有多个case,每个case输入一行01符号串(长度不超过20),1表示反面朝上,0表示正面朝上。
Output
对于每组case,如果可以翻,输出最少需要翻动的次数,否则输出NO。
Sample Input
01 011
Sample Output
NO 1
Author
wangye
Recommend
wangye
题目大意:中文题不解释
题目分析:bfs+状压。没事练习一下双向bfs。
详情请见代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
using namespace std;
const int N = 1050000;
bool flag[2][N];
struct node
{
int state,step;
}ss,now;
struct que
{
struct node t[N];
int head,tail;
void init()
{
head = tail = 0;
}
bool empty()
{
return head == tail;
}
void push(struct node a)
{
t[tail] = a;
tail ++;
if(tail >= N)
tail %= N;
}
struct node top()
{
return t[head];
}
void pop()
{
head ++;
if(head >= N)
head %= N;
}
}q[2];
char s[30];
int main()
{
int i,j,k;
while(~scanf("%s",s))
{
if(strcmp(s,"1") == 0)
{
printf("1\n");
continue;
}
q[0].init();
q[1].init();
ss.state = 0;
ss.step = 0;
int len = strlen(s) - 1;
//printf("%d\n",len);
for(i = 0;i <= len;i ++)
{
if(s[len - i] == '1')
ss.state |= 1<<i;
}
memset(flag,0,sizeof(flag));
if(ss.state == 0)
{
printf("0\n");
continue;
}
q[0].push(ss);
flag[0][ss.state] = 1;
ss.state = 0;
q[1].push(ss);
flag[1][ss.state] = 1;
bool ok = false;
j = 0;
int ans;
while(!q[0].empty() && !q[1].empty())
{
for(i = 0;i < 2;i ++)
{
while(!q[i].empty() && q[i].top().step == j)
{
now = q[i].top();
//printf("%d:%d %d %d\n",i,now.state,now.step,j);
// system("pause");
q[i].pop();
ss.step = now.step + 1;
for(k = 0;k <= len;k ++)
{
int msk = 0;
ss.state = now.state;
if(k == 0)
msk = 3;
else if(k == len)
{
msk |= 1<<len;
msk |= 1<<(len - 1);
}
else
{
msk |= 1<<k;
msk |= 1<<(k - 1);
msk |= 1<<(k + 1);
}
ss.state ^= msk;
if(!flag[i][ss.state])
{
flag[i][ss.state] = 1;
if(flag[1 - i][ss.state])
{
ok = true;
ans = j + j + 1 + i;
break;
}
q[i].push(ss);
}
}
if(ok)
break;
}
if(ok)
break;
}
if(ok)
break;
j ++;
}
if(ok)
printf("%d\n",ans);
else
printf("NO\n");
}
return 0;
}
//687MS 10568K
杭电那么些跑0ms的什么情况?难道这题我想复杂了????