原题 http://acm.hdu.edu.cn/showproblem.php?pid=3328
题目:
Flipper
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 664 Accepted Submission(s): 405
Problem Description
Little Bobby Roberts (son of Big Bob, of Problem G) plays this solitaire memory game called Flipper. He starts with n cards, numbered 1 through n, and lays them out in a row with the cards in order left-to-right. (Card 1 is on the far left; card n is on the far right.) Some cards are face up and some are face down. Bobby then performs n - 1 flips — either right flips or left flips. In a right flip he takes the pile to the far right and flips it over onto the card to its immediate left. For example, if the rightmost pile has cards A, B, C (from top to bottom) and card D is to the immediate left, then flipping the pile over onto card D would result in a pile of 4 cards: C, B, A, D (from top to bottom). A left flip is analogous.
The very last flip performed will result in one pile of cards — some face up, some face down. For example, suppose Bobby deals out 5 cards (numbered 1 through 5) with cards 1 through 3 initially face up and cards 4 and 5 initially face down. If Bobby performs 2 right flips, then 2 left flips, the pile will be (from top to bottom) a face down 2, a face up 1, a face up 4, a face down 5, and a face up 3.
Now Bobby is very sharp and you can ask him what card is in any position and he can tell you!!! You will write a program that matches Bobby’s amazing feat.
Input
Each test case will consist of 4 lines. The first line will be a positive integer n (2 ≤ n ≤ 100) which is the number of cards laid out. The second line will be a string of n characters. A character U indicates the corresponding card is dealt face up and a character D indicates the card is face down. The third line is a string of n - 1 characters indicating the order of the flips Bobby performs. Each character is either R, indicating a right flip, or L, indicating a left flip. The fourth line is of the form m q1 q2 … qm, where m is a positive integer and 1 ≤ qi ≤ n. Each qi is a query on a position of a card in the pile (1 being the top card, n being the bottom card). A line containing 0 indicates end of input.
Output
Each test case should generate m + 1 lines of output. The first line is of the form
Pile t
where t is the number of the test case (starting at 1). Each of the next m lines should be of the form
Card qi is a face up k.
or
Card qi is a face down k.
accordingly, for i = 1, ..,m, where k is the number of the card.
For instance, in the above example with 5 cards, if qi = 3, then the answer would be
Card 3 is a face up 4.
Sample Input
5
UUUDD
RRLL
5 1 2 3 4 5
10
UUDDUUDDUU
LLLRRRLRL
4 3 7 6 1
0
Sample Output
Pile 1
Card 1 is a face down 2.
Card 2 is a face up 1.
Card 3 is a face up 4.
Card 4 is a face down 5.
Card 5 is a face up 3.
Pile 2
Card 3 is a face down 1.
Card 7 is a face down 9.
Card 6 is a face up 7.
Card 1 is a face down 5.
思路:
一开始n张牌平铺在面前,牌上的数字分别是1到n,初始有状态正面朝向,然后进行移动操作。最后查询第几张的数字是几,面朝方向。
左操作是把最左边的那组牌移到它旁边的那组上面,具体操作类似于空当接龙,每次只移动最表层那一个,并且移动之后纸牌翻面。
每操作一次纸牌都会翻面,所以只需要记录每张牌的翻面次数,最后再对2取余即可。
而顺序记录只需要两个栈和一个暂存的队列就行了,因为每次操作都是从栈顶一个个弹出。
注意最后一次移动会使两组牌合并到一起,所以单独考虑。
代码:
#include <iostream>
#include"string.h"
#include"cstdio"
#include"stdlib.h"
#include"algorithm"
#include"math.h"
#include"queue"
#include"stack"
using namespace std;
int main()
{
const int N=105;
int n;
int t=0;
int arr[N];
for(int i=0; i<N; i++)
{
arr[i]=i+1;
}
while(scanf("%d",&n),n)
{
t++;
char flag[N];
char buzhou[N];
int cishu[N];
int chaxun[N];
memset(flag,0,sizeof(flag));
memset(buzhou,0,sizeof(buzhou));
memset(cishu,0,sizeof(cishu));
memset(chaxun,0,sizeof(chaxun));
getchar();
gets(flag);
gets(buzhou);
int m=0;
scanf("%d",&m);
for(int i=0;i<m;i++)
{
scanf("%d",&chaxun[i]);
}
for(int i=0; i<n; i++)
{
if(flag[i]=='U') cishu[i]=1;
}
stack <int> front;
stack <int> behind;
queue <int> q;
front.push(arr[0]);
behind.push(arr[n-1]);
int l=1;
int r=n-2;
for(int i=0; i<=n-3; i++)
{
if(buzhou[i]=='R')
{
for(int k=r+1; k<=n-1; k++)
{
cishu[k]++;
}
q.push(arr[r]);
r--;
while(!behind.empty())
{
int temp=behind.top();
q.push(temp);
behind.pop();
}
while(!q.empty())
{
int temp=q.front();
behind.push(temp);
q.pop();
}
}
else if(buzhou[i]=='L')
{
for(int k=l-1; k>=0; k--)
{
cishu[k]++;
}
q.push(arr[l]);
l++;
while(!front.empty())
{
int temp=front.top();
q.push(temp);
front.pop();
}
while(!q.empty())
{
int temp=q.front();
front.push(temp);
q.pop();
}
}
}
if(buzhou[n-2]=='R')
{
for(int k=r+1; k<=n-1; k++)
{
cishu[k]++;
}
while(!front.empty())
{
int temp=front.top();
behind.push(temp);
front.pop();
}
while(!behind.empty())
{
int temp=behind.top();
q.push(temp);
behind.pop();
}
}
else if(buzhou[n-2]=='L')
{
for(int k=l-1; k>=0; k--)
{
cishu[k]++;
}
while(!behind.empty())
{
int temp=behind.top();
front.push(temp);
behind.pop();
}
while(!front.empty())
{
int temp=front.top();
q.push(temp);
front.pop();
}
}
for(int i=0;i<n;i++)
{
cishu[i]=cishu[i]%2;
}
int ans[N];
int i=n-1;
memset(ans,0,sizeof(ans));
while(!q.empty())
{
ans[i--]=q.front();
q.pop();
}
printf("Pile %d\n",t);
for(i=0; i<m; i++)
{
int tt=chaxun[i]-1;
if(cishu[ans[tt]-1]==1)
printf("Card %d is a face up %d.\n",tt+1,ans[tt]);
else
printf("Card %d is a face down %d.\n",tt+1,ans[tt]);
}
}
return 0;
}