zoukankan      html  css  js  c++  java
  • UVA 11134 Fabled Rooks

    https://vjudge.net/problem/UVA-11134

    题目

    你的任务是在 $n imes n$ 的棋盘上放 $n$ 个车,使得任意两个车不互相攻击,且第 $i$ 个车在一个给定的矩形 $R_i$ 之内。用4个整数 $xl_i, yl_i, xr_i, yr_i (1leqslant xl_ileqslant xr_i leqslant n, 1leqslant yl_i leqslant yr_i leqslant n)$ 描述第i个矩形,其中 $(xl_i, yl_i)$ 是左上角的坐标, $(xr_i, yr_i)$ 是右下角坐标,则第 $i$ 个车的位置 $(x,y)$ 必须满足 $xl_ileqslant x leqslant xr_i, yl_ileqslant y leqslant yr_i$。如果无解,输出IMPOSSIBLE;否则输出 $n$ 行,依次为第 $1,2,cdots,n$ 个车的坐标。

    题解

    终于不做搜索了!

    贪心……

    将两个维度分开

    法1:

    将每个区间按左端点从小到大排序

    1.l1<l2时,l1到min(r1,l2)的范围内随便选,不会丢解,因此下面不再考虑左端点不等的情况

    2.l1=l2时,需要考虑r1和r2的关系

    显然先选r2小的……

    如果按照这个策略还会出错,因为每次选择后每个区间能选的部分都会缩小一截,因为我们之前考虑的全是能选的区间……

    解决方法是选择一个点后,把所有左端点相等的区间的左端点向后移动一个单位,然后再次排序……

    由于重新排序有点麻烦,因此可以使用优先队列(堆)

    法2:

    将每个区间按右端点大小排序

    显然先选右端点小的……

    然后从左至右依次尝试……需要一个数组记录每个点是否选择

    可以验证从左至右不会丢解

    (感觉像是知道了答案编过程……还是记下,防止以后忘记)

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define REP(r,x,y) for(register int r=(x); r<(y); r++)
    #define REPE(r,x,y) for(register int r=(x); r<=(y); r++)
    #ifdef sahdsg
    #define DBG(...) printf(__VA_ARGS__)
    #else
    #define DBG(...)
    #endif
    
    struct node {
    	int xl,yl,xr,yr;
    	int id;
    } nodes[5007];
    inline bool cmp1(const node& n1, const node &n2) {
    	return n1.xr<n2.xr || (n1.xr==n2.xr && n1.xl<n2.xl);
    }
    inline bool cmp2(const node& n1, const node &n2) {
    	return n1.yr<n2.yr || (n1.yr==n2.yr && n1.yl<n2.yl);
    }
    bool visx[5007];
    bool visy[5007];
    int main() {
    	#ifdef sahdsg
    	freopen("in.txt", "r", stdin);
    	#endif
    	int n;
    	while(~scanf("%d", &n) && n) {
    		int ans[5007][2];
    		memset(visx,0,sizeof visx);
    		memset(visy,0,sizeof visy);
    		
    		REP(i,0,n) {
    			nodes[i].id=i;
    			scanf("%d%d%d%d",
    				&nodes[i].xl,
    				&nodes[i].yl,
    				&nodes[i].xr,
    				&nodes[i].yr);
    		}
    		sort(nodes,nodes+n,cmp1);
    		REP(i,0,n) {
    			bool f=true;
    			REPE(j,nodes[i].xl,nodes[i].xr) {
    				if(!visx[j]) {
    					visx[j]=1;
    					f=false;
    					ans[nodes[i].id][0]=j;
    					break;
    				}
    			}
    			if(f) {
    				goto wa;
    			}
    		}
    		sort(nodes,nodes+n,cmp2);
    		REP(i,0,n) {
    			bool f=true;
    			REPE(j,nodes[i].yl,nodes[i].yr) {
    				if(!visy[j]) {
    					visy[j]=1;
    					f=false;
    					ans[nodes[i].id][1]=j;
    					break;
    				}
    			}
    			if(f) {
    				goto wa;
    			}
    		}
    		REP(i,0,n) {
    			printf("%d %d
    ", ans[i][0], ans[i][1]);
    		}
    		
    		continue;
    		wa:;
    		puts("IMPOSSIBLE");
    		
    	}
    	
    	return 0;
    }
    
  • 相关阅读:
    Eureka相关相关接口和代码位置
    Zookeeper(4)---ZK集群部署和选举
    Zookeeper(3)---java客户端的使用
    Zookeeper(2)---节点属性、监听和权限
    玩转百度地图API(地图,坐标,标记,添加控件,2D图,混合图,智能搜索,地址解析器,信息窗口)
    HTML+CSS系列:CSS选择器(标签、ID、类、通配符、后代、子元素、并集、伪类)
    Git系列:常用命令
    Linux系列:快捷键、目录结构、用户目录
    mybatis-plus系统化学习之更新-AR-主键-service
    mybatis-plus系统化学习之查询专题
  • 原文地址:https://www.cnblogs.com/sahdsg/p/10479634.html
Copyright © 2011-2022 走看看