POJ 1231The Alphabet Game【題解報告|思維】

題目鏈接
在這裏插入圖片描述
如果用直線劃分空間的話,能不能做到每個區域裏只有一種字母,或者沒有字母


我們可以設置四個數組來r[],l[],u[],d[]r[], l[], u[], d[]來儲存讀入時覆蓋沒種數字的矩形的最右、左、上、下四個位置座標。(可以認爲r[]r[]儲存的是對第i個數來說,其右側直線的最右座標值,因爲這時如果直線比r[]r[]還靠右,那麼這個數字必然無法分到同一個矩形裏,另三個數組的意義同樣)

然後慢慢更新這四組座標,更新的依據是如果某個riri在另一個rjrjljlj之間,那麼如果要劃分的話,至少是要在rjrj處畫直線,否則第jj個數就無法分到同一個矩形裏,所以這時更新ri=rjri=rj,同樣的對l,u,dl, u, d做同樣的更新。

        for(int i = 0; i < k; i++) {
            for(int j = 0; j < k; j++) {
                if(i == j) continue;
                if(r[i] > r[j] && r[i] < l[j]) r[i] = r[j];
                if(l[i] < l[j] && l[i] > r[j]) l[i] = l[j];
                if(u[i] > u[j] && u[i] < d[j]) u[i] = u[j];
                if(d[i] < d[j] && d[i] > u[j]) d[i] = d[j];
            }

那麼在所有的數據都更新完之後,我們在進行一次check,看看是否還有某個riliri(或li)在rjljrj和lj之間同時uidiui(或di)ujdjuj和dj之間(就是某個矩形與另一個矩形有重合部分),如果有,那麼進行劃分時,必然會導致第i個數或者第j個數無法分到同一個矩形裏。


bool check(int n) {
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++) {
            if(i == j) continue;
            if(((r[j] >= r[i] && r[j] <= l[i]) || (l[j] <= l[i] && l[j] >= r[i]))
                && ((u[j] >= u[i] && u[j] <= d[i]) || (d[j] <= d[i] && d[j] >= u[i])))
                    return 0;
        }
    }
    return 1;
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <map>
#include <vector>
#include <numeric>
 
using namespace std;
#define MAX(x,y) ((x)>(y)?(x):(y))
#define MIN(x,y) ((x)<(y)?(x):(y))
#define INF 1000000000
 
int r[27], l[27], u[27], d[27];
 
bool check(int n) {
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++) {
            if(i == j) continue;
            if(((r[j] >= r[i] && r[j] <= l[i]) || (l[j] <= l[i] && l[j] >= r[i]))
                && ((u[j] >= u[i] && u[j] <= d[i]) || (d[j] <= d[i] && d[j] >= u[i])))
                    return 0;
        }
    }
    return 1;
}
 
int main() {
    int t, k ,p;
    scanf("%d", &t);
    while(t--) {
        scanf("%d%d", &k, &p);
        for(int i = 0; i < k; i++) {
            int rr = INF, ll = 0, uu = INF, dd = 0,tmp, tmpp;
            for(int j = 0; j < p; j++) {
                scanf("%d%d", &tmp, &tmpp);
                rr = min(rr, tmp), ll = max(ll, tmp), uu = min(uu, tmpp), dd = max(dd, tmpp);
            }
            r[i] = rr, l[i] = ll, u[i] = uu, d[i] = dd;
        }
        for(int i = 0; i < k; i++) {
            for(int j = 0; j < k; j++) {
                if(i == j) continue;
                if(r[i] > r[j] && r[i] < l[j]) r[i] = r[j];
                if(l[i] < l[j] && l[i] > r[j]) l[i] = l[j];
                if(u[i] > u[j] && u[i] < d[j]) u[i] = u[j];
                if(d[i] < d[j] && d[i] > u[j]) d[i] = d[j];
            }
        }
        if(check(k)) puts("YES");
        else puts("NO");
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章