UVA—11134 Fabled Rooks 传说中的车

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;
}

猜你喜欢

转载自blog.csdn.net/lky_ac/article/details/83991718