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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章