UVA-11134 Fabled Rooks 传说中的车
刚开始时想直接用回溯法过,试了两种回溯方法都超时了。
后来用贪心法写了一遍,老是WA,卡了差不多两小时发现自己输出中的IMPOSSIBLE写成IMPOSSBILE了,改了之后就AC了。难受。
总的来说还是要注意细节。
对于题目来说注意到行列无关所以可以分别对行和列进行处理,先将各个区间其按区间左端点的大小排序,然后历遍各个区间,每次选择区间从左边开始没被选过的点作为一个解就可以了,如果在一个区间中全部的点都被选择过,则无解。
AC代码如下
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=5050;
struct Node{
int f,s,id; // 区间,f为左端点,s为右端点,id为初始序列号
bool operator < (Node a){
return a.s>s||(a.s==s&&a.f>f);
}
}x[maxn],y[maxn];
int n;
int vx[maxn],vy[maxn];
int ax[maxn],ay[maxn];
bool slove(Node* a,int* vis,int* ans){
for(int i=0;i<n;i++){
int kase=0;
for(int j=a[i].f;j<=a[i].s;j++){
if(!vis[j]){
vis[j]=kase=1;
ans[a[i].id]=j;
break;
}
}
if(!kase) return false;
}
return true;
}
int main(){
while(scanf("%d",&n)&&n){
for(int i=0;i<n;i++){
scanf("%d%d%d%d",&x[i].f,&y[i].f,&x[i].s,&y[i].s);
x[i].id=y[i].id=i;
}
memset(vx,0,sizeof(vx));
memset(vy,0,sizeof(vy));
sort(x,x+n);
sort(y,y+n);
if(slove(x,vx,ax)&&slove(y,vy,ay)){
for(int i=0;i<n;i++) printf("%d %d\n",ax[i],ay[i]);
}
else printf("IMPOSSIBLE\n");
}
return 0;
}