题目链接: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;
}
}