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
",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	",i,c[i]);
    }
    printf("
");
}
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
",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
",v,cur);
                if(cur) sta[pos].push(cur);
                cur = getC(v,v);
//                printf("2    v = %d cur = %d
",v,cur);
                if(cur) sta[pos].push(cur);
                cur = getC(u,v-1);
//                printf("3    v = %d cur = %d
",v,cur);
                if(cur) sta[pos].push(cur);
                cur = getC(1,u-1);
//                printf("4    v = %d cur = %d
",v,cur);
                if(cur) sta[pos].push(cur);
                break;
            }
            pre[e[j].l] = j;
        }
//        debug(n);
    }
    printf("%d
",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("
");
            else printf(" ");
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/EchoZQN/p/14548256.html