JZOJ621420190614tetris
Posted paul-guderian
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JZOJ621420190614tetris相关的知识,希望对你有一定的参考价值。
题目
这是一道和俄罗斯方块有关的有趣题目
底面宽度为\\(N\\),高度无限,初始时方块高度为\\(A_i\\)
你可以决定每次会下落一个\\(1 \\times K\\)或者\\(K \\times 1\\)的方块
你需要在10000次内把所有方块消完,输出方案
$N , K A_i \\le 50 $
题解
#include<bits/stdc++.h>
using namespace std;
const int N=51,K=51;
int n,m,k,a[N],b[N*K],c[K],mn,mx,ans;
struct optint x,y;Ans[10010];
void put(int op,int x)Ans[++ans]=(opt)op,x;
bool judge()
for(int i=0;i<n;++i)(c[i%k]+=a[i])%=k;
int tmp=c[0];for(int i=0;i<m;++i)if(c[i]!=tmp)return false;
tmp=c[m];for(int i=m;i<k;++i)if(c[i]!=tmp)return false;
return true;
int main()
freopen("tetris.in","r",stdin);
freopen("tetris.out","w",stdout);
scanf("%d%d",&n,&k);m=n%k;
for(int i=0;i<n;++i)scanf("%d",&a[i]);
if(!judge())return puts("-1"),0;
for(int i=1;i<n;++i)while(a[i]<a[i-1])put(1,i),a[i]+=k;
mn=mx=a[0];for(int i=1;i<n;++i)mn=min(mn,a[i]),mx=max(mx,a[i]);
mx-=mn;for(int i=0;i<n;++i)a[i]-=mn,b[a[i]]++;
for(int i=mx;i;--i)b[i]+=b[i+1];
for(int i=1;i<=mx;++i)while(b[i]+k<=n)put(2,n-b[i]-k),b[i]+=k;
for(int i=0;i<k;++i)c[i]=0;
for(int i=1;i<=mx;++i)c[n-b[i]]++;
for(int i=k-1;i;--i)c[i]+=c[i+1];
mx-=c[0];
int tmp=(mx-1)/k+1;mx=tmp*k;
for(int i=0;i<k-1;++i)
for(int j=0;j<tmp;++j)put(1,i);
a[i]=mx-c[i+1];
for(int i=k-1;i<n;++i)a[i]=0;
mx=0;for(int i=m;i<=k-1;++i)mx=max(mx,a[i]);
for(int i=0;i<n;++i)while(a[i]<mx)put(1,i),a[i]+=k;
for(int i=0;i<n;++i)a[i]-=mx;
if(n%k)
mx=0;for(int i=0;i<m;++i)mx=max(mx,a[i]);
for(int i=0;i<m;++i)while(a[i]<mx)put(1,i),a[i]+=k;
for(int i=m;i<n;i+=k)for(int j=0;j<mx;++j)put(2,i);
printf("%d\\n",ans);
for(int i=1;i<=ans;++i)printf("%d %d\\n",Ans[i].x,Ans[i].y+1);
return 0;
以上是关于JZOJ621420190614tetris的主要内容,如果未能解决你的问题,请参考以下文章