POJ 2965 解题报告

这道题我是用最基本的BFS过的。一个简单的优化是每个位置的switch都可以简化为与一个数的异或,这样就不必对该行该列一个个异或了,效率应该能提高一些。

thestoryofsnow2965Accepted1424K750MSC++2259B
/* 
ID: thestor1 
LANG: C++ 
TASK: poj2965 
*/
#include <iostream>
#include <fstream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <limits>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <algorithm>
#include <cassert>

using namespace std;
const int N = 4;

int queue[65536];
int visited[65536] = {false};
int previous[65536];
int step[65536][2];

bool isOpen(int handler, int r, int c)
{
	return (handler & (1 << (N * r + c)));
}

int switchh(int handler, int r, int c)
{
	return (handler ^ (1 << (N * r + c)));
}

int switchRowCol(int handler, int r, int c)
{
	for (int i = 0; i < N; ++i)
	{
		handler = switchh(handler, r, i);
	}
	for (int i = 0; i < N; ++i)
	{
		if (i == r)
		{
			continue;
		}

		handler = switchh(handler, i, c);	
	}
	return handler;
}

void printHandler(int handler)
{
	printf("[debug]handler(%d):\n", handler);
	for (int r = 0; r < N; ++r)
	{
		for (int c = 0; c < N; ++c)
		{
			if (isOpen(handler, r, c))
			{
				printf("+");
			}
			else
			{
				printf("-");
			}
		}
		printf("\n");
	}
}

int main()
{
	int handler = 0;
	char line[N + 1];
	for (int r = 0; r < N; ++r)
	{
		scanf("%s", line);
		for (int c = 0; c < N; ++c)
		{
			if (line[c] == '+')
			{
				handler |= 1 << (N * r + c);
			}
		}
	}
	
	queue[0] = handler;
	int front = 0, rear = 1;

	visited[handler] = true;

	int nh;
	while (front < rear)
	{
		int h = queue[front];
		front++;

		if (h == 0)
		{
			break;
		}

		for (int r = 0; r < N; ++r)
		{
			for (int c = 0; c < N; ++c)
			{
				nh = switchRowCol(h, r, c);
				if (!visited[nh])
				{
					previous[nh] = h;
					step[nh][0] = r;
					step[nh][1] = c;
					queue[rear] = nh;
					rear++;
					visited[nh] = true;

					// printf("\n");

					// printHandler(h);
					// printf("---------->\n");
					// printHandler(nh);

					// printf("\n");
				}
			}
		}
	}

	// printHandler(handler);

	int h = 0;
	std::vector<pair<int, int> > steps;
	while (h != handler)
	{
		// printHandler(h);
		steps.push_back(make_pair(step[h][0], step[h][1]));
		h = previous[h];
	}

	printf("%lu\n", steps.size());
	for (int i = steps.size() - 1; i >= 0; --i)
	{
		printf("%d %d\n", steps[i].first + 1, steps[i].second + 1);
	}

	return 0;  
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值