8.5-237-uva11134-Fabled Rooks-问题分解-贪心

行和列是无关的,当且仅当行列都满足条件,则存在解

不失一般性 现在只考虑x坐标(x为列的编号)

题目等价于找这样的一个序偶满足:用一系列闭区间[xli,xri]覆盖整数点1,2,3.....n 且每个整数对应于唯一的一个区间 (区间与整数点是一对一的)故可用贪心法 从第一个整数点1开始 对闭区间进行遍历 找到覆盖1的区间中 右端点最小的一个(找最小的b与找最小值的方法类似,即先假设最小,再循环判断,有更小的更新minb) 如果存在则标记这个区间表示已经用过并建立映射(因为是一对一的,用了之后不能再用,所以一定要标记)

同理对2也这样处理,,,,以此类推一直到n 如果每个整数都存在这样的一个对应 则解存在 否则一旦有一个不满足 就不可能存在解


#include<cstdio>
#include<iostream>

#include <algorithm>
using namespace std;
const int maxn=5000+5;
int x1[maxn],y1[maxn],x2[maxn],y2[maxn],x[maxn],y[maxn];
int n;
bool solve(int a[],int b[],int c[]){
	fill(c, c+n, -1);
	
	
	for(int col=1;col<=n;col++){
		int minb=n+1;
		int rock=-1;//记录符合条件的(a[i],b[i])的编号i 
		for(int i=0;i<n;i++){
			if(a[i]<=col&&b[i]>=col&&c[i]<0&&b[i]<minb){
				minb=b[i];
				rock=i;
			}
		}
		if(rock<0) return false;
		else c[rock]=col; //映射并完成标记 
	}
	return true;
	
}
int main(){
	
	while(cin>>n&&n){
		for(int i=0;i<n;i++)
		cin>>x1[i]>>y1[i]>>x2[i]>>y2[i];
		if(solve(x1,x2,x)&&solve(y1,y2,y))
		for(int i=0;i<n;i++)
		cout<<x[i]<<" "<<y[i]<<endl;
		else cout<<"IMPOSSIBLE"<<endl;
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值