zoukankan      html  css  js  c++  java
  • 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('
    ')
    #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;
    	}
    }
    

      

  • 相关阅读:
    5.1点击4个按钮显示相应的div
    4.1邮箱的全选,全不选,反选
    3.1点击3个按钮变宽变高变色
    2.4点击按钮填色
    2.3点击菜单显示div再点击就隐藏
    2.2 点击按钮改变文本框中的文字内容
    linux系统编程视频 百度网盘下载
    Linux网络编程视频 百度网盘
    Sage Crm 权限原理分析
    Sage CRM 平衡区域树结构
  • 原文地址:https://www.cnblogs.com/qq936584671/p/9269295.html
Copyright © 2011-2022 走看看