D. Unshuffling a Deck 模拟

D. Unshuffling a Deck 模拟

题目大意:

给你一副牌,最开始按照第 \(i\) 个位置是 \(c[i]\) 的一个排列,你可以进行一种操作:

  • 选择一个大小 \(k\) ,把这 \(n\) 张牌分成 \(k\) 个部分,分别是 \(D1,D2,...,Dk\)
  • 然后这 \(k\) 个部分,翻转(每个部分内部的顺序不变),所以就是 \(Dk,Dk-1,...,D1\)

问经过多少操作,这 \(n\) 张牌变成有序的,经验证最多 \(n\) 此操作一定可以。

所以请你输出一个答案, \(0<=q<=n\) ,然后输出每一次操作是怎么分的,不要求操作数最少。

\(n<=52\)

题解:

一个很简单的模拟题,稍微想想就应该可以想出,但是写起来不是那么简单。

之前写过类似的题目,用结构体来处理。

思路:

  • 我每次操作只需要找到一个就可以了,就是让一部分和一部分连接就可以了
  • 每一个部分是连续的一串数。
  • 所以对于第 \(i\) 个部分,我只要判断这个 r +1 的位置是不是在前面,如果是,那么进行一次操作
  • 进行完操作之后,更新 \(c[i]\) ,更新结构体
#include <bits/stdc++.h>
using namespace std;
const int maxn = 110;
typedef long long ll;
struct node{
    int l,r,id;
    node(int l=0,int r=0,int id=0):l(l),r(r),id(id){}
}e[maxn];
int c[maxn],pre[maxn],now,cnt;
stack<int>sta[maxn];
void getE(int n){
    now = 1;
    e[1] = node(c[1],c[1],1);
    for(int i=2;i<=n;i++){
        if(c[i]==e[now].r+1) e[now].r ++;
        else e[++now] = node(c[i],c[i],i);
    }
}
int getC(int l,int r){
//    printf("getC: l = %d r = %d\n",l,r);
    int ans = 0;
    for(int k=l;k<=r;k++) {
        for (int h = e[k].l; h <= e[k].r; h++) {
            c[++cnt] = h;
            ans++;
        }
    }
    return ans;
}
void debug(int n){
    for(int i=1;i<=n;i++){
        printf("c[%d]=%d\t",i,c[i]);
    }
    printf("\n");
}
int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) {
        scanf("%d",&c[i]);
    }
    int pos = 0;
    for(int i=1;i<=n;i++){
        getE(n),cnt = 0;
        if(now==1) break;
        memset(pre,-1,sizeof(pre));
        for(int j=1;j<=now;j++){
//            printf("i = %d j = %d now = %d\n",i,j,now);
            if(pre[e[j].r+1]!=-1){
                int u = pre[e[j].r+1],v = j;
                ++pos;
                int cur = getC(v+1,now);
//                printf("1    v = %d cur = %d\n",v,cur);
                if(cur) sta[pos].push(cur);
                cur = getC(v,v);
//                printf("2    v = %d cur = %d\n",v,cur);
                if(cur) sta[pos].push(cur);
                cur = getC(u,v-1);
//                printf("3    v = %d cur = %d\n",v,cur);
                if(cur) sta[pos].push(cur);
                cur = getC(1,u-1);
//                printf("4    v = %d cur = %d\n",v,cur);
                if(cur) sta[pos].push(cur);
                break;
            }
            pre[e[j].l] = j;
        }
//        debug(n);
    }
    printf("%d\n",pos);
    for(int i=1;i<=pos;i++){
        printf("%d ",sta[i].size());
        while(!sta[i].empty()){
            printf("%d",sta[i].top());sta[i].pop();
            if(sta[i].empty()) printf("\n");
            else printf(" ");
        }
    }
    return 0;
}
posted @ 2021-03-17 11:14  EchoZQN  阅读(60)  评论(0编辑  收藏  举报