2012年12月4日 星期二

SGU 147 Black-white king

題目看的懂就簡單了,但題目寫的真的不是很清楚

題目翻譯+注釋:

白王:走8格,但是要以最少的步數走到黑王
黑王:走8格,但是要以最少的步數走到黑王
黑白王:走8格,但是不能走到可以以較少步數走到的地方

走的順序:
白王先,黑王次,黑白王後

白王跟黑王要見面,黑白王要在他們碰面前走到某個人的所在位置並殺掉他
問有可能或不可能(白王跟黑王看不到黑白王)

==================以下是題解

枚舉走的步數,1步2步...

黑白王在第 i 步走到的一定是一個『正方形的外框』

而白王跟黑王,因為要走最少的,所以其中的一個方向

每次都必須要走至少一格,並避免無法跟對方相遇,會有另外的一個限制
      其實就是『他跟對方』走到這裡的兩條線段的交集
      因為他之後走到的一定會是另一個人的上面一層
      同層就代表多走了某些步數,且定義為面對面的範圍跟走的範圍是一樣的
      所以才可以直接算交集

所以其實他的所在位置都只會是某一條線(平行Y軸或X軸)

只要判斷這條線跟黑白王的框框有沒有相交即可

//By momo
#include<cstdio>
#include<algorithm>
#define INF 999999999
using namespace std;

int n, bx, by, wx, wy, xx, xy, dis, ans = INF;
int check(int sx, int sy, int ex, int ey, int st){
    int dir = ex>sx?1:-1;
    for(int i = 1; i <= st; i++){
        int x = sx+dir*i, l, r;
        l = max(1, max(sy-i, ey-(dis-i)));
        r = min(n, min(sy+i, ey+(dis-i)));
        if((x == xx-i && !(r < xy-i || xy+i < l))
        || (x == xx+i && !(r < xy-i || xy+i < l))
        || (abs(xx-x)<i && l <= xy-i && xy-i <= r)
        || (abs(xx-x)<i && l <= xy+i && xy+i <= r))
            return i;
    }
    return INF;
}

int main(){
    scanf("%d%d%d", &n, &bx, &by);
    scanf("%d%d%d%d", &wx, &wy, &xx, &xy);
    if(abs(bx-wx) < abs(by-wy)){
        swap(bx, by);
        swap(wx, wy);
        swap(xx, xy);
    }
    dis = abs(bx-wx);
    ans = min(check(bx,by,wx,wy,dis/2-1), check(wx,wy,bx,by,dis/2-1));
    if(ans == INF) printf("NO\n%d\n", dis-1);
    else printf("YES\n%d\n", ans);
}

沒有留言:

張貼留言