1. 程式人生 > >2018icpc青島現場賽 F題(思維,倍增,塊交換)

2018icpc青島現場賽 F題(思維,倍增,塊交換)

題目: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;	
}