USACO Wormholes 解题报告

新加的USACO题都有youtube讲解,感觉非常好。由于section的位置和数据的规模(~12),可以知道就用直观的想法写就可以。即产生所有的pair,每产生一个就看下是否有环。标准程序在检测是否有环部分非常简洁,3,4行代码就搞定了。我这里面又用了一次递归。当然,他这里也是利用了数据规模很小的特点。用递归判断是否有环需要注意的地方(也是我第一次提交挂的原因)是,需要看next的时候(即往右边走的时候)遇到的洞是否之前进去过了,而不应该看从“隧道”到达的点是否经过了。即只考虑地上的情况。因为有种情况是一个点地上遇到一次(通过向右走),后来通过“隧道”到达一次,但之后向右走到头了。就不会陷入题中要求的“无限循环”中。

/* 
ID: thestor1 
LANG: C++ 
TASK: wormhole 
*/
#include 
#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include 
#include   
#include   
#include   
#include 

using namespace std;

bool checkpair(const vector &pairs, int cur, const int N, std::vector &visited, const vector &next)
{
	// cout<<"[debug]cur: "< &pairs, const vector &next, const int N)
{
	std::vector visited(N, false);
	for (int i = 0; i < N; ++i)
	{
		for (int k = 0; k < N; ++k)
		{
			visited[k] = false;
		}
		
		if (checkpair(pairs, i, N, visited, next))
		{
			return true;
		}
	}
	return false;
}

void formpair(vector &pairs, vector &paired, int cur, const vector &next, const int N, int &cnt)
{
	if (cur == N)
	{
		// cout<<"[debug]pairs: ";
		// for (int i = 0; i < pairs.size(); ++i)
		// {
		// 	cout<>N;
	vector > wormholes(N);
	for (int i = 0; i < N; ++i)
	{
		int x, y;
		fin>>x>>y;
		wormholes[i] = make_pair(x, y);
	}

	vector next(N, -1);
	for (int i = 0; i < N; ++i)
	{
		int n = -1;
		for (int j = 0; j < N; ++j)
		{
			if (wormholes[j].second == wormholes[i].second && wormholes[j].first > wormholes[i].first)
			{
				if (n < 0 || wormholes[j].first < wormholes[n].first)
				{
					n = j;
				}
			}
		}
		next[i] = n;
	}

	// cout<<"[debug]next: ";
	// for (int i = 0; i < N; ++i)
	// {
	// 	cout< pairs(N);
	vector paired(N, false);
	int cnt = 0;
	formpair(pairs, paired, 0, next, N, cnt);
	fout<


你可能感兴趣的:(USACO)