题目链接:https://cn.vjudge.net/problem/UVA-11134
这题和我之前做的多校上的一题十分像,就是一个贪心。具体可以先看看这篇bolg:https://blog.csdn.net/super_son/article/details/80330290
这和多校那题很像,唯一不同就是多了一步分析,这里的行和列是无关的,所以我们可以把行和列分开来看,行进行一次贪心,列进行一次贪心,这就和多校那题解题思路差不多了。
所以这题可以和多校那题一样使用优先队列解决,代码如下:
#include <bits/stdc++.h>
using namespace std;
struct Node{
int id, x, y;
Node(int id=0, int x=0, int y=0):id(id),x(x),y(y){}
bool operator > (const Node& n) const{
return y > n.y || (y == n.y && x > n.x);
}
};
const int maxn = 5000 + 10;
Node r[maxn], c[maxn], ans[maxn];
int main(){
int n;
while(cin >> n && n){
for(int i = 1; i <= n; ++i){
r[i].id = c[i].id = i;
cin >> r[i].x >> c[i].x >> r[i].y >> c[i].y;
}
int cnt = 1;
priority_queue<Node, vector<Node>, greater<Node> > qr;
priority_queue<Node, vector<Node>, greater<Node> > qc;
while(cnt <= n){
for(int i = 1; i <= n; ++i)
if(r[i].x == cnt) qr.push(r[i]);
for(int i = 1; i <= n; ++i)
if(c[i].x == cnt) qc.push(c[i]);
if(!qr.empty()) {
int t = qr.top().id;
qr.pop();
if(r[t].y >= cnt) ans[t].x = cnt;
else { cnt = 0; break; }
} else {
cnt = 0;
break;
}
if(!qc.empty()) {
int t = qc.top().id;
qc.pop();
if(c[t].y >= cnt) ans[t].y = cnt;
else { cnt = 0; break; }
} else {
cnt = 0;
break;
}
cnt++;
}
if(cnt) {
for(int i = 1; i <= n; ++i)
cout << ans[i].x << " " << ans[i].y << endl;
}else {
cout << "IMPOSSIBLE" << endl;
}
}
return 0;
}
由于这题的特殊性,因为每个Rook都必须要有个位置能放下,否则就直接输出-1。所以我们就可以按照那些Ronk的右端点对Rook进行从小到大的排序,然后按照这个顺序依次为每个Ronk安排位置,这样一来一旦某个Rook无法安排下了,就直接输出-1。代码如下:
#include <bits/stdc++.h>
using namespace std;
struct Interval{
int L, R, id;
bool operator < (const Interval& p) const {
return R < p.R || (R == p.R && L < p.L);
}
};
const int maxn = 5005;
int n, vis[maxn];
bool solve(Interval t[], int a[]){
sort(t+1, t+1+n);
memset(vis, 0, sizeof(vis));
for(int j,i = 1; i <= n; ++i){
for(j = t[i].L; j <= t[i].R; ++j)
if(!vis[j]){
vis[j] = 1;
a[t[i].id] = j;
break;
}
if(j > t[i].R) return false;
}
return true;
}
int main(){
Interval r[maxn], c[maxn];
while(scanf("%d", &n) != EOF && n){
for(int i = 1; i <= n; ++i){
r[i].id = c[i].id = i;
scanf("%d%d%d%d", &r[i].L, &c[i].L, &r[i].R, &c[i].R);
}
int R[maxn], C[maxn];
if(solve(r, R) && solve(c, C)){
for(int i = 1; i <= n; ++i)
printf("%d %d\n", R[i], C[i]);
}else {
printf("IMPOSSIBLE\n");
}
}
return 0;
}