题目大意:
桌面上方了N 张牌,有正面朝上和反面朝上的。
然后执行两种操作,R和L
R就是把最右边的一堆牌反转一下放在右边数第二个上面
也是是
如果
A
B
D C
执行了R就是
C
B
A
D
了
那么用并查集维护他们在每个堆上的位置,用线段树维护他们的正反状态。
最后会合成一个堆,所以他们最后的位置是独一无二的,
直接找就可以了
我写的很麻烦,其实按照这个思路。直接暴力模拟就行了。数据很小。
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #define lson num<<1,s,mid #define rson num<<1|1,mid+1,e #define maxn 105 using namespace std; int tre[maxn<<2]; int set[maxn]; int pos[maxn]; int cnt[maxn]; char str[maxn]; int tcnt; int find(int x) { if(x==set[x])return x; else return set[x]=find(set[x]); } void pushdown(int num) { if(tre[num]) { tre[num<<1]^=1; tre[num<<1|1]^=1; tre[num]=0; } } void build(int num,int s,int e) { tre[num]=0; if(s==e) { tre[num]=str[tcnt]==‘U‘?1:0; tcnt++; return; } int mid=(s+e)>>1; build(lson); build(rson); } void update(int num,int s,int e,int l,int r) { if(l<=s && r>=e) { tre[num]^=1; return; } pushdown(num); int mid=(s+e)>>1; if(l<=mid)update(lson,l,r); if(r>mid)update(rson,l,r); } void query(int num,int s,int e,int pos,int val) { if(s==e) { if(tre[num]==0) printf("Card %d is a face down %d.",val,s); else printf("Card %d is a face up %d.",val,s); puts(""); return; } pushdown(num); int mid=(s+e)>>1; if(pos<=mid)query(lson,pos,val); else query(rson,pos,val); } int main() { int n; int CASE=1; while(scanf("%d",&n)!=EOF && n) { scanf("%s",str); tcnt=0; build(1,1,n); for(int i=1;i<=n;i++) { pos[i]=cnt[i]=1; } for(int i=1;i<=n;i++)set[i]=i; scanf("%s",str); int len=strlen(str); int cntr=0,cntl=0; for(int i=0;i<len;i++) { if(str[i]==‘R‘) { int tmp=find(n); for(int i=1;i<=n;i++) { if(find(i)==tmp) { pos[i]=cnt[tmp]-pos[i]+1; } } int f=n-cntr-1; int xx=find(f); for(int i=1;i<=n;i++) { if(find(i)==xx)pos[i]+=cnt[tmp]; } set[xx]=tmp; cnt[tmp]+=cnt[xx]; update(1,1,n,n-cntr,n); cntr++; } else { int tmp=find(1); for(int i=1;i<=n;i++) { if(find(i)==tmp) { pos[i]=cnt[tmp]-pos[i]+1; } } int f=1+cntl+1; int xx=find(f); for(int i=1;i<=n;i++) { if(find(i)==xx)pos[i]+=cnt[tmp]; } set[xx]=tmp; cnt[tmp]+=cnt[xx]; update(1,1,n,1,1+cntl); cntl++; } //for(int i=1;i<=n;i++) //{ // printf("%d ",pos[i]); //} //puts(""); } int m; printf("Pile %d\n",CASE++); scanf("%d",&m); int a; while(m--) { scanf("%d",&a); for(int i=1;i<=n;i++) { if(pos[i]==a){ query(1,1,n,i,a); break; } } } } return 0; }
hdu 3328 Flipper,布布扣,bubuko.com
原文:http://blog.csdn.net/u010709592/article/details/23294665