• 【杂题】[CodeForces 1172D] Nauuo and Portals【构造】


    Description

    有一个n*n的网格,你需要在上面设置一些传送门,传送门由两个配对的格子组成,从一个进入会立刻从另一个同一方向出来。

    现在有n个人从第1列出发向右走,位于(i,1)的人要走到(ri,n)
    n个人从第一行出发向下走,位于(1,i)的人要走到(n,ci)
    求一种设置传送门的方案。

    n<=1000

    Solution

    很有意思的一个构造。

    我们先考虑第一行第一列
    如果他们都是一条直线走过去,那就直接转化成了一个n-1的子问题。

    否则我们记位于(p,1)的人要去(1,n),位于(1,q)的人要去(n,1)
    我们可以直接在(p,1)和(1,q)放一个传送门,相应的修改第一行的人和第一列的人所在位置,那么一样转化成了一个n-1的子问题。

    这样就可以用不超过n个传送门解决了,时间复杂度O(n)

    题解说开1000是因为checker是n^2的...

    Code

    #include <bits/stdc++.h>
    #define fo(i,a,b) for(int i=a;i<=b;++i)
    #define fod(i,a,b) for(int i=a;i>=b;--i)
    #define N 1005
    using namespace std;
    int r[N],r1[N],c[N],c1[N],n,ans[N][4];
    int main()
    {
    	cin>>n;
    	fo(i,1,n) scanf("%d",&r[i]),r1[r[i]]=i;
    	fo(i,1,n) scanf("%d",&c[i]),c1[c[i]]=i;
    	int cnt=0;
    	fo(i,1,n)
    	{
    		int p=r1[i],q=c1[i];
    		if(p==i&&q==i) continue;
    		cnt++;
    		ans[cnt][0]=p,ans[cnt][1]=i,ans[cnt][2]=i,ans[cnt][3]=q;
    		swap(r1[r[i]],r1[r[p]]);
    		swap(c1[c[i]],c1[c[q]]);
    		swap(r[i],r[p]);
    		swap(c[i],c[q]);
    	}
    	printf("%d
    ",cnt);
    	fo(i,1,cnt) printf("%d %d %d %d
    ",ans[i][0],ans[i][1],ans[i][2],ans[i][3]);
    }
    
  • 相关阅读:
    JAVA字符串格式化-String.format()的使用
    分布式文件系统MFS(moosefs)实现存储共享(第二版)
    iOS 动画学习
    复制对象(一)copy和mutableCopy方法
    iOS-获取当前网页的 url 和 title 和 html
    排序算法 c实现
    常用正则表达式
    iOS-获取的NSDate date时间与实际相差8个小时解决方案
    网络爬虫基本原理(二)
    网络爬虫基本原理(一)
  • 原文地址:https://www.cnblogs.com/BAJimH/p/11020131.html
Copyright © 2020-2023  润新知