日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

P7115-[NOIP2020]移球游戏【构造】

發布時間:2023/12/3 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P7115-[NOIP2020]移球游戏【构造】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正題

題目鏈接:https://www.luogu.com.cn/problem/P7115


題目大意

n+1n+1n+1個柱子,前面nnn個上面各有mmm個球,球有nnn種顏色,每種mmm個。

你每次可以把一個柱子最上面的球放到另一個上面,要求在820000820000820000次內使得同種顏色的球都在同一個柱子上。

輸出方案

2≤n≤50,2≤m≤4002\leq n\leq 50,2\leq m\leq 4002n50,2m400


解題思路

這題好難啊,用的是洛谷題解上的做法。

首先我們枚舉一種顏色xxx,將這種顏色標記為111其他都為000

然后開始的狀態是這樣的

然后考慮先構造一個全部都是000的豎列

我們先記錄第一柱的111的個數tmptmptmp,然后把第n?1n-1n?1柱子的tmptmptmp個丟進第n+1n+1n+1柱,然后把第一柱分離到后面兩個柱子(111的放到nnn000的放到n+1n+1n+1

然后把原來的000放到第一柱,然后分離第二柱,如果是000放到第一柱否則放到第n+1n+1n+1柱(如果第一柱已經滿了就放進n+1n+1n+1柱)


然后交換一下柱子序號(用個數組存一下就好了)就變成了

然后再考慮構造全111

我們把同理把第111柱分裂到第nnn和第n+1n+1n+1柱就變成了

此時第n+1n+1n+1柱子上面全部是111而第nnn柱上面都是000,然后此時我們再把剩下nnn個柱子依次分離就能把所有的111提到最上面,然后把所有的111集合就好了。

最后弄出n?1n-1n?1個全000柱和一個全111柱我們就可以把全一柱去掉然后縮小nnn的值。

一直重復到n=2n=2n=2時我們發現我們的方法不再適用,需要特別處理。

我們按照前面的方法把第一柱分離到222333

然后把000111丟到第一個柱子,然后再把111丟進第333個柱子

然后分離第二個柱子就好了

然后這樣就能過了


code

#include<cstdio> #include<cstring> #include<algorithm> #include<vector> using namespace std; const int N=410; int n,m,a[N][N],cnt[N],p[N]; vector<int> aL,aR; void mov(int x,int y){aL.push_back(x);aR.push_back(y);a[y][++cnt[y]]=a[x][cnt[x]--];return; } int count(int x,int y){int ans=0;for(int i=1;i<=m;i++)ans+=(a[x][i]==y);return ans; } int main() {scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){for(int j=1;j<=m;j++)scanf("%d",&a[i][j]);cnt[i]=m;p[i]=i;}p[n+1]=n+1;for(int k=n;k>=3;k--){int tmp=count(p[1],k);for(int i=1;i<=tmp;i++)mov(p[k],p[k+1]);for(int i=1;i<=m;i++)if(a[p[1]][cnt[p[1]]]==k)mov(p[1],p[k]);else mov(p[1],p[k+1]);for(int i=1;i<=m-tmp;i++)mov(p[k+1],p[1]);for(int i=1;i<=m;i++)if(a[p[2]][cnt[p[2]]]==k)mov(p[2],p[k+1]);else if(cnt[p[1]]<m)mov(p[2],p[1]);else mov(p[2],p[k+1]);swap(p[1],p[k]);swap(p[2],p[k+1]);for(int i=1;i<k;i++){int tmp=count(p[i],k);for(int j=1;j<=tmp;j++)mov(p[k],p[k+1]);for(int j=1;j<=m;j++)if(a[p[i]][cnt[p[i]]]==k)mov(p[i],p[k]);else mov(p[i],p[k+1]);swap(p[i],p[k+1]);swap(p[k],p[i]);}for(int i=1;i<k;i++){while(a[p[i]][cnt[p[i]]]==k)mov(p[i],p[k+1]);while(cnt[p[i]]<m)mov(p[k],p[i]);}}int tmp=count(p[1],1);for(int i=1;i<=tmp;i++)mov(p[2],p[3]);for(int i=1;i<=m;i++)if(a[1][cnt[p[1]]]==1)mov(p[1],p[2]);else mov(p[1],p[3]);for(int i=1;i<=m-tmp;i++)mov(p[3],p[1]);for(int i=1;i<=tmp;i++)mov(p[2],p[1]);while(cnt[p[3]])mov(p[3],p[2]);for(int i=1;i<=tmp;i++)mov(p[1],p[3]);for(int i=1;i<=m;i++)if(a[2][cnt[p[2]]]==1)mov(p[2],p[3]);else mov(p[2],p[1]);printf("%d\n",aL.size());for(int i=0;i<aL.size();i++)printf("%d %d\n",aL[i],aR[i]);return 0; }

總結

以上是生活随笔為你收集整理的P7115-[NOIP2020]移球游戏【构造】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。