现在的位置: 首页 > 综合 > 正文

Pixel Shuffle poj 2789

2013年11月27日 ⁄ 综合 ⁄ 共 3916字 ⁄ 字号 评论关闭

一道置换题,置换类型的题目都可以转化成若干个有向圈的模型进行思考,此题先把题目给出操作组合得到的置换求出来,分解成循环,而循环之间相互是不会影响的,单独的把每个循环看成一个有向圈,每次操作都会是所有的边指向下一个节点,所以经过k(k为循环中元素个数的倍数)次操作可以是每条边指向自己,所以答案就是每个循环元素个数的最小公倍数


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cctype>
#include <utility>   
#include <map>
#include <string>  
#include <climits> 
#include <set>
#include <string>    
#include <sstream>
#include <utility>   
#include <ctime>

using std::priority_queue;
using std::vector;
using std::swap;
using std::stack;
using std::sort;
using std::max;
using std::min;
using std::pair;
using std::map;
using std::string;
using std::cin;
using std::cout;
using std::set;
using std::queue;
using std::string;
using std::istringstream;
using std::make_pair;
using std::getline;
using std::greater;
using std::endl;

typedef long long LL;


const int MAXN((1 << 10)+5);
int N;

void subs_1(int (*ma1)[MAXN], int (*ma2)[MAXN], bool flag)
{
	memcpy(ma1, ma2, sizeof(ma2[0])*N);
}

void subs_2(int (*ma1)[MAXN], int (*ma2)[MAXN], bool flag)
{
	for(int i = 0; i < N; ++i)
		for(int j = 0; j < N; ++j)
			if(flag)
				ma1[N-j-1][i] = ma2[i][j];
			else
				ma1[i][j] = ma2[N-j-1][i];
}

void subs_3(int (*ma1)[MAXN], int (*ma2)[MAXN], bool flag)
{
	for(int i = 0; i < N; ++i)
		for(int j = 0; j < N; ++j)
			ma1[i][N-j-1] = ma2[i][j];
}

void subs_4(int (*ma1)[MAXN], int (*ma2)[MAXN], bool flag)
{
	memcpy(ma1, ma2, sizeof(ma2[0])*N);
	for(int i = N/2; i < N; ++i)
		for(int j = 0; j < N; ++j)
			ma1[i][N-j-1] = ma2[i][j];
}

void subs_5(int (*ma1)[MAXN], int (*ma2)[MAXN], bool flag)
{
	memcpy(ma1, ma2, sizeof(ma2[0])*N);
	int temp = N/2;
	for(int i = N/2; i < N; ++i)
		for(int j = 0; j < N; ++j)
			ma1[N-i-1+temp][j] = ma2[i][j];
}

void subs_6(int (*ma1)[MAXN], int (*ma2)[MAXN], bool flag)
{
	int ti = 0;
	for(int i = 0; i < N; i += 2, ++ti)
		for(int j = 0; j < N; ++j)
			if(flag)
				ma1[ti][j] = ma2[i][j];
			else
				ma1[i][j] = ma2[ti][j];
	ti = N/2;
	for(int i = 1; i < N; i += 2, ++ti)
		for(int j = 0; j < N; ++j)
			if(flag)
				ma1[ti][j] = ma2[i][j];
			else
				ma1[i][j] = ma2[ti][j];
}

void subs_7(int (*ma1)[MAXN], int (*ma2)[MAXN], bool flag)
{
	int tj;
	for(int i = 0; i < N; i += 2)
	{
		tj = 0;
		for(int j = 0; j < N; tj += j&1, ++j)
			if(flag)
				ma1[i][j] = ma2[i^(j&1)][tj];
			else
				ma1[i^(j&1)][tj] = ma2[i][j];
	}
	for(int i = 1; i < N; i += 2)
	{
		tj = N/2;
		for(int j = 0; j < N; tj += j&1, ++j)
			if(flag)
				ma1[i][j] = ma2[i^1^(j&1)][tj];
			else
				ma1[i^1^(j&1)][tj] = ma2[i][j];
	}
}

void (*fp[7])(int (*ma1)[MAXN], int (*ma2)[MAXN], bool flag) =
	{subs_1, subs_2, subs_3, subs_4, subs_5, subs_6, subs_7};

LL gcd(LL a, LL b)
{
	LL temp;
	while(b)
	{
		temp = a%b;
		a = b;
		b = temp;
	}
	return a;
}

LL lcm(LL a, LL b)
{
	return a/gcd(a, b)*b;
}

bool vis[MAXN*MAXN];

LL solve(int *arr)
{
	int tn = N*N;
	memset(vis, 0, sizeof(vis[0])*tn);
	LL ans = 1LL;
	for(int i = 0; i < tn; ++i)
		if(!vis[arr[i]])
		{
			int t1 = arr[i];
			int t2 = arr[t1];
			int count = 1;
			vis[t1] = true;
			while(t2 != t1)
			{
				vis[t2] = true;
				t2 = arr[t2];
				++count;
			}
			ans = lcm(count, ans);
		}
		return ans;
}

string str;
string op[35];
int op_c;
int ma[2][MAXN][MAXN];
int subm[MAXN*MAXN];
map<string, pair<int, bool> > mp;

int main()
{
	mp.insert(make_pair(string("id"), make_pair(0, true)));
	mp.insert(make_pair(string("id-"), make_pair(0, false)));
	mp.insert(make_pair(string("rot"), make_pair(1, true)));
	mp.insert(make_pair(string("rot-"), make_pair(1, false)));
	mp.insert(make_pair(string("sym"), make_pair(2, true)));
	mp.insert(make_pair(string("sym-"), make_pair(2, false)));
	mp.insert(make_pair(string("bhsym"), make_pair(3, true)));
	mp.insert(make_pair(string("bhsym-"), make_pair(3, false)));
	mp.insert(make_pair(string("bvsym"), make_pair(4, true)));
	mp.insert(make_pair(string("bvsym-"), make_pair(4, false)));
	mp.insert(make_pair(string("div"), make_pair(5, true)));
	mp.insert(make_pair(string("div-"), make_pair(5, false)));
	mp.insert(make_pair(string("mix"), make_pair(6, true)));
	mp.insert(make_pair(string("mix-"), make_pair(6, false)));
	//int T;
	//scanf("%d", &T);
//	while(T--)
	while(~scanf("%d", &N))
	{
	//	scanf("%d", &N);
		while(getchar() != '\n');

		getline(cin, str);

		istringstream in(str);
		op_c = 0;

		while(in >> op[op_c])
			++op_c;

		int cur = 1, last = 0;
		int ti = 0;
		for(int i = 0; i < N; ++i)
			for(int j = 0; j < N; ++j)
				ma[last][i][j] = ti++;
		for(int i = op_c-1; i >= 0; --i)
		{
			pair<int, bool> temp;
			temp = mp[op[i]];
			fp[temp.first](ma[cur], ma[last], temp.second);
			cur ^= 1;
			last ^= 1;
		}
		ti = 0;
		for(int i = 0; i < N; ++i)
			for(int j = 0; j < N; ++j)
				subm[ti++] = ma[last][i][j];
		printf("%I64d\n", solve(subm));
	}
	return 0;
}

抱歉!评论已关闭.