1. 程式人生 > >P2520 [HAOI2011]向量

P2520 [HAOI2011]向量

挺喜歡這個大佬的解題:https://www.cnblogs.com/five20/p/8427795.html    這篇文章也是借鑑大佬的部落格。不過還是希望有別的補充。

題意:給你座標(x, y)然後產生(x,y)(-x,y)(x,-y)(-x,-y)(y,x) (-y,x) (y,-x) (-y,-x)讓這八個座標任意組合,問是否能配成(a, b)座標。

然後,其實(x, y)和(-x,-y)提公因式化為同一項

其他同理 

我們先證明一個東西為後面的證明打下基礎!

還可以說明 h1,h3具有同奇同偶性,  h2,h4具有同奇同偶性

那我們來分析一下有解的情況:

  情況一:h1+h2 為偶數, h2+h4為偶數

      那麼對於a來說一定能被gcd(x, y)*2整除。

  情況二:h1+h2 為奇數, h2+h4為奇數

      兩邊同時加x+y, 因為奇數+1等於偶數,則就是情況一:(a+x+y)%gcd(x, y)*2==0  (為什麼可以隨便新增x,y,在變數中增加和減少不影響(注意:區分集合))

  情況三:h1+h2 為奇數, h2+h4為偶數

      兩邊加x,則為情況一:(a+x)%gcd(x, y)*2==0

  情況四:h1+h2 為偶數, h2+h4為奇數

      兩邊加y,則為情況一:(a+y)%gcd(x, y)*2==0

這只是說明了一個式子有解,下一個式子是相同套路。

#include<cstdio>
#define ll long long
ll k;
ll gcd(ll a, ll b){ return b == 0 ? a : gcd(b, a%b); }
bool check(ll a, ll b){ return a%k == 0 && b%k == 0; }

int main(){
    int t;
    scanf("%d", &t);
    while (t--){
        ll x, y, a, b;
        scanf("
%lld%lld%lld%lld", &a, &b, &x, &y); k = gcd(a, b)*2; if (check(x, y) || check(x + a, y + b) || check(x + b, y + a) || check(x + a + b, y + a + b)){ printf("Y\n"); } else printf("N\n"); } }