2018icpc青岛现场赛 F题(思维,倍增,块交换)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wwwlps/article/details/83828525

题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4063

对于n的大小,对战轮数有规律可循,k<(n&-n)方可分配方案,其余Impossible.

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include <vector>
#include <cmath>
#include<queue>
#include <stack>
#include <map>
#define maxn 1005
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
int t,n,k,max_round;
int ch[maxn][maxn];
void solve()
{
	int len=1;
	while(len<=k)
	{
		for(int i=len;i<2*len;i++)//枚举每一轮 
		{
			for(int j=1;j<=n;j+=2*len)//每一轮里头的每一块,此循环的次数就是块交换的长度 
			{
				for(int u=j;u<j+len;u++)
				{
					ch[i][u]=ch[i-len][u+len];
				}
				for(int u=j+len;u<j+2*len;u++)
				{
					ch[i][u]=ch[i-len][u-len];
				}
			}
		}
		len*=2;
	}
	
}
int main()
{
	cin>>t;
	while(t--)
	{
		cin>>n>>k;
		if(k>=(n&-n))
		{
			cout << "Impossible\n";
			continue;
		}	
		for(int i=1;i<=n;i++)
		{
			ch[0][i]=i;
		}
		max_round=(n&-n)-1;
		solve();
		for(int i=1;i<=k;i++)
		{
			for(int j=1;j<=n;j++)
			{
				if(j==1)
					cout << ch[i][j];
				else
					cout << ' ' << ch[i][j];
			}
			cout << endl;
		}
		
	} 
	return 0;	
} 

猜你喜欢

转载自blog.csdn.net/wwwlps/article/details/83828525