Codeforces Round #492 (Div. 2) [Thanks, uDebug!] C Tesla

题目链接:http://codeforces.com/contest/996/problem/C

一道很麻烦的模拟题。

中间两排是车辆,外面两排是停车场,停车场属于指定车辆,只有对应车辆才能进入,对应为0的停车场任何车辆都无法进入,车辆可以开到中间两排的空地,题目要求求出使所有车辆开到指定停车场的方法。

很显然,只要存在任意一个空地,所有车辆都能开进停车场。

所以判断是否存在空地就能判断是否有解,但模拟的过程是很令人头疼,当你利用一块空地时,总共要走5步才能使目标车辆向目标方向移动1步,最坏情况下,一辆车要移动5*50步才能到达目标地点,100辆车则会有25000步,这就超过了题目的步数限制。

假如把这两排抽象成一个圆形,使其旋转直到复原,就会出现每一辆车与每一个停车位都对应的情况,转圈要100*100步,满足要求。

每次把圆转动一个单位,就检查一次是否有车可以进入停车场,时间复杂度为100*100。

为了便于操作,找出任意一块空地,每对其进行2*n次操作就会回到原点。

但这样做会出错,以下给出图解为什么会错:

我们看到第一个和倒数第二个,可以认为圆旋转了90度,这是没有错的,但是我们是以空地回到原点为标准,所以转动完后,是从第一个到了最后一个,所以会漏掉1在左上角的情况。

所以每把圆转动一个单位,就检查两次(在转到一半的时候一次,结束时一次)是否有车可以进入停车场,时间复杂度为100*100*2。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stack>
#include<map>
#include<vector>
#include<queue>
#include<set>
#include<iomanip>
#include<cctype> 
using namespace std;
const int MAXN=1e5+5;
const int INF=1<<30;
const long long mod=1e9+7;
const double eps=1e-8;
#define ll long long
#define edl putchar('\n')
#define sscc ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define ROF(i,a,b) for(int i=a;i>=b;i--)
#define FORLL(i,a,b) for(ll i=a;i<=b;i++)
#define ROFLL(i,a,b) for(ll i=a;i>=b;i--)
#define mst(a) memset(a,0,sizeof(a))
#define mstn(a,n) memset(a,n,sizeof(a))
#define zero(x)(((x)>0?(x):-(x))<eps)
struct num
{
	int a,x,y;
};
ll n,k,a[55][7];
queue<num> q;
void swap(int x1,int y1,int x2,int y2)
{
	//cout<<x1<<" "<<y1<<" "<<x2<<" "<<y2<<endl;
	if(a[x1][y1]==0&&a[x2][y2]==0)
	return ;
	if(a[x1][y1]==0)
	swap(x1,x2),swap(y1,y2);
	num t;
	t.a=a[x1][y1],t.x=x2,t.y=y2;
	q.push(t);
	a[x1][y1]=a[x2][y2];
	a[x2][y2]=t.a;
}
void judg(int i)
{
	if(a[i][2]!=0&&a[i][2]==a[i][1])
	{
		num t;
		t.a=a[i][2];
		a[i][2]=0;
		t.x=i,t.y=1;
		q.push(t);
	}
	if(a[i][3]!=0&&a[i][3]==a[i][4])
	{
		num t;
		t.a=a[i][3];
		a[i][3]=0;
		t.x=i,t.y=4;
		q.push(t);
	}
}
int main()
{	
	cin>>n>>k;
	FOR(j,1,4)
	FOR(i,1,n)
	cin>>a[i][j];
	{
		FOR(i,1,n)
		{
			judg(i);
		}
		if(n*2==k&&q.empty())
		{
			cout<<-1<<endl;
			return 0;
		}
	}
	int mx=0,my,tol=2*n;
	FOR(J,2,3)
	if(mx==0)
	FOR(I,1,n)
	{
		if(a[I][J]==0)
		{
			mx=I,my=J;
			break;
		}
	}
	if(my==3)
	swap(mx,3,mx,2),my=2;
	while(tol--)
	{
		FOR(i,mx+1,n)
		swap(mx++,my,i,my);
		swap(mx,my++,mx,my);
		ROF(i,n-1,1)
		swap(mx--,my,i,my);
		FOR(i,1,n)
		{
			judg(i);
		}
		swap(mx,my--,mx,my);
		FOR(i,2,mx)
		swap(mx++,my,i,my);
		/*cout<<endl;
		FOR(i,2,3)
		cout<<a[1][i]<<" "<<a[2][i]<<endl;
		cout<<endl;*/
		FOR(i,1,n)
		{
			judg(i);
		}
	}
	cout<<q.size()<<endl;
	while(!q.empty())
	{
		num t=q.front();
		q.pop();
		cout<<t.a<<" "<<t.y<<" "<<t.x<<endl;
	}
}

  

猜你喜欢

转载自www.cnblogs.com/qq936584671/p/9269295.html