1. 程式人生 > 實用技巧 >2020杭電多校 5C / HDU 6816 - Boring Game

2020杭電多校 5C / HDU 6816 - Boring Game

HDU 6816 - Boring Game


題意

\(n\)張紙平鋪在桌面上,一同從左向右摺疊\(k\)

給出一個長度為\(2*n*2^k\)的排列\(P\)

將紙張從上往下,正反交替標記為排列\(P\)中的值

問將紙張展開後得到的從上往下、從左往右的序列




思路

不會找規律,直接暴力就完事了

vector模擬將紙還原的過程(即最終狀態為上圖右半部分狀態)

所以需要還原\(k\)

每一次將當前合法的上半部分倒序合併到下半部分,如圖

最後將還原出來的\(2n\)個vector倒序輸出即可




程式碼

(312ms/1000ms)

#include<bits/stdc++.h>
using namespace std;

vector<int> v[555555];

void solve()
{
    int n,k,m,d,cur;
    cin>>n>>k;
    m=n<<(k+1);
    for(int i=1;i<=m;i++)
    {
        cin>>d;
        v[i].clear();
        v[i].push_back(d);
    }
    cur=1;
    for(int t=1;t<=k;t++)
    {
        int mid=(cur+m)>>1;
        for(int i=cur;i<=mid;i++)
        {
            int siz=v[i].size();
            for(int j=siz-1;j>=0;j--) //從後往前加入下方vector內
                v[mid+mid-i+1].push_back(v[i][j]);
        }
        cur=mid+1;
    }
    for(int i=m-n*2+1;i<=m;i++)
    {
        int siz=v[i].size();
        for(int j=siz-1;j>=0;j--) //從後往前輸出
            cout<<v[i][j]<<(i==m&&j==0?'\n':' ');
    }
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int T;cin>>T;
    while(T--)
        solve();
    return 0;
}