zoj 2050 || poj 1753 Flip Game(状态压缩 简单BFS)

这题也算是经典题了,好早之前就看到了,一直没啥想法做,知道是状态压缩,可是没细想过。

A过上道题,就想找个状态压缩的试试哈,就找到这个题啦。

很容易想到,4*4的格子,用一个16位的存下(用int绰绰有余~)就好,这样的话,一个状态就可以用一个数字表示了,标记状态是否用过,用65535的数组就够了。

这个^=好神奇,我开始用了俩位运算表示这个,囧。。。A掉之后觉得时间好慢,看别人的,才看到这个符号。。囧。。

位运算好神奇。。。我开始用的四个方向,先把位置换算成4*4中得坐标,再找上下左右四个方向,慢了几十ms。。。别人用的直接+4 -4 +1 -1(后俩得判断是否越当前行的界),这个很快~

int st_change(int st, int x)
{
	st ^= (1 << x);
		
	int a = x/4, b = x % 4;
	for(int i=0; i<8; i+=2)
	{
		int xx = a + dir[i];
		int yy = b + dir[i+1];
		if( xx >= 0 && xx < 4 && yy >= 0 && yy < 4 )
		{
			int p = ( xx * 4 + yy );
			st ^= (1 << p);
		}
	}
	return st;
}

int st_change(int st, int x)
{
	st ^= (1 << x);
	
	if( x + 4 < 16 )
		st ^= (1 << (x + 4));
	if( x - 4 >= 0 )
		st ^= (1 << (x - 4));
	if( x % 4 < 3 && x + 1 < 16 )
		st ^= (1 << (x + 1));
	if( x % 4 > 0 && x - 1 >= 0 )
		st ^= (1 << (x - 1));
	return st;
}

完整版:


#include <set>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#include <iostream>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define FOR(i,s,t) for(int i=(s); i<(t); i++)
#define BUG puts("here!!!")
#define STOP system("pause")
#define file_r(x) freopen(x, "r", stdin)
#define file_w(x) freopen(x, "w", stdout)

using namespace std;

const int MAX = 70000;
bool used[MAX];
typedef pair<int,int> pii;
queue<pii> q;
int st_change(int st, int x)
{
	st ^= (1 << x);
	
	if( x + 4 < 16 )
		st ^= (1 << (x + 4));
		
	if( x - 4 >= 0 )
		st ^= (1 << (x - 4));
		
	if( x % 4 < 3 && x + 1 < 16 )
		st ^= (1 << (x + 1));
		
	if( x % 4 > 0 && x - 1 >= 0 )
		st ^= (1 << (x - 1));
	return st;
}

int solve(int st)
{
	while( !q.empty() ) q.pop();
	
	if( st == 0 || st == 65535 )
		return 0;
		
	q.push(make_pair(st, 0));
	
	while( !q.empty() )
	{
		st = q.front().first;
		int t = q.front().second;
		q.pop();
		FOR(i, 0, 16)
		{
			int now = st_change(st, i);
			if( now == 0 || now == 65535 )
				return t + 1;
			if( !used[now] )
			{
				used[now] = true;
				q.push(make_pair(now, t+1));
			}
		}
	}
	return -1;
}	
int main()
{
	int ncases, st;
	char s[10];
	
	scanf("%d", &ncases);
	
	while( ncases-- )
	{
		st = 0;
		memset(used, false, sizeof(used));
		
		FOR(i, 0, 4)
		{
			scanf("%s", &s);
			FOR(k, 0, 4)
				if( s[k] == 'b' )
					st = st | ( 1 << (i * 4 + k) );
		}
		used[st] = true;
		
		int ans = solve( st );
		
		if( ans == -1 )
			puts("Impossible");
		else
			printf("%d\n", ans);
			
		if( ncases ) puts("");
	}
	
return 0;
}


你可能感兴趣的:(File,System,pair)