24h購物| | PChome| 登入
2013-12-01 18:25:57| 人氣1,817| 回應0 | 上一篇 | 下一篇

[UVA] 10416 - Folding My T-Shirt

推薦 0 收藏 0 轉貼0 訂閱站台

Problem F
Folding My T-Shirt
Input: standard input
Output: standard output
Time Limit: 2 seconds
Memory Limit: 16 MB

I have a T-Shirt. When I don't wear it any more, I fold it up. For most of the time, I can find a line so that the parts of the T-shirt on both sides are symmetrical. Then, I can fold it along that line. But sadly, I cannot find such a line for some strange(really really strange, see sample input ^_^) T-shirts.

In the example above, I can fold the T-shirt along the dash line, then, I got the figure on the right. Could you tell me if I can succeed?

Input

The first line of the input contains a single integer t(t<=20) indicating the number of test cases. Each test case begins with a line containing a single integer n(3<=n<=100) indicating the number of points of the polygon. In the next n lines each contain a pair of integers (xi,yi), indicating the position of the points. The points are given in the counter-clockwise order. The T-Shirt is valid. i.e not self-crossing. But the T-Shirt maybe not convex.

Output

For each test case, output a line corresponding the answer. Answer 'Yes' if the T-Shirt can be folded, 'No' otherwise.

Sample Input
2
3
0 0
5 0
1 1
8
1 0
2 0
2 1
-2 1
-2 0
-1 0
-1 -3
1 -3

Sample Output
No
Yes


The 2nd OIBH Online Programming Contest. Author: Rujia Liu


題目描述:

給一個簡單多邊形,問能不能使用一條線使之對稱。

題目解法:

1) 當點數 n 為奇數時
   窮舉 i-th 點和 (i+(n-1)/2)-th 與
(i+(n-1)/2)-th 的中點拉線,
查看是否為對稱關係。


2) 當點數 n 為偶數時
   2.1 窮舉 i-th 點和 (i+n/2)-th
點拉線,查看是否為對稱關係。

   2.2 窮舉 i-th 點與 (i+1)-th 點的中點 和 (i+n/2)-th
點與 (i+n/2+1)-th 點的中點拉線,查看是否為對稱關係。


計算時特別小心浮點數誤差,經過實驗後,用 double 計算時產生一堆 WA。

先將所有點的值都乘上 2,因此在取中點時不會有浮點數問題,而在檢查能不能左右對稱時,採用從線的兩側同時檢查,查看中點也在線上,且線的法向量與拉出向量外積 = 0

#include <stdio.h>
#include <math.h>
#include <set>
#include <algorithm>
using namespace std;
int n, x[105], y[105];
int main() {
    int testcase;
    int i, j, k;
    scanf("%d", &testcase);
    while(testcase--) {
        scanf("%d", &n);
        for(i = 0; i < n; i++) {
            scanf("%d %d", &x[i], &y[i]);
            x[i] *= 2;
            y[i] *= 2;
        }
        int ret = 0;
        if(n < 3)    ret = 1;
        if(n&1) {// odd
            int idx = n/2;
            for(i = 0; i < n; i++) {
                int mx, my;
                int a, b, c;
                mx = (x[(i+idx)%n]+x[(i+idx+1)%n])/2;
                my = (y[(i+idx)%n]+y[(i+idx+1)%n])/2;
                a = my - y[i];
                b = x[i] - mx;
                c =  - (a*x[i] + b*y[i]);
                int flag = 1;
                for(j = 0; j < n; j++) {
                    int ax = x[(i+1+j)%n];
                    int ay = y[(i+1+j)%n];
                    int bx = x[(i-1-j+n+n)%n];
                    int by = y[(i-1-j+n+n)%n];
                    mx = (ax+bx)/2;
                    my = (ay+by)/2;
                    if(a*mx + b*my + c != 0 || (ax-bx)*b != (ay-by)*a)
                        flag = 0;
                }
                if(flag) {
                    ret = 1;
                    break;
                }
            }
        } else {
            int idx = n/2;
            for(i = 0; i < n; i++) {
                int mx, my, a, b, c;
                a = y[(i+idx)%n] - y[i];
                b = x[i] - x[(i+idx)%n];
                c =  - (a*x[i] + b*y[i]);
                int flag = 1;
                for(j = 0; j < n; j++) {
                    int ax = x[(i+1+j)%n];
                    int ay = y[(i+1+j)%n];
                    int bx = x[(i-1-j+n+n)%n];
                    int by = y[(i-1-j+n+n)%n];
                    mx = (ax+bx)/2;
                    my = (ay+by)/2;
                    if(a*mx + b*my + c != 0 || (ax-bx)*b != (ay-by)*a)
                        flag = 0;
                }
                if(flag) {
                    ret = 1;
                    break;
                }
            }           
            for(i = 0; i < n; i++) {
                int mx1, my1, mx2, my2;
                int a, b, c;
                mx1 = (x[i] + x[(i+1)%n])/2;
                my1 = (y[i] + y[(i+1)%n])/2;
                mx2 = (x[(i+idx)%n] + x[(i+idx+1)%n])/2;
                my2 = (y[(i+idx)%n] + y[(i+idx+1)%n])/2;
                a = my2 - my1;
                b = mx1 - mx2;
                c =  - (a*mx1 + b*my1);
                int flag = 1, mx, my;
                for(j = 0; j < n; j++) {
                    int ax = x[(i+1+j)%n];
                    int ay = y[(i+1+j)%n];
                    int bx = x[(i-j+n+n)%n];
                    int by = y[(i-j+n+n)%n];
                    mx = (ax+bx)/2;
                    my = (ay+by)/2;
                    if(a*mx + b*my + c != 0 || (ax-bx)*b != (ay-by)*a)
                        flag = 0;
                }
                if(flag) {
                    ret = 1;
                    break;
                }
            }
        }
        puts(ret ? "Yes" : "No");
    }
    return 0;
}

台長: Morris
人氣(1,817) | 回應(0)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 教育學習(進修、留學、學術研究、教育概況) | 個人分類: UVA |
此分類下一篇:[UVA][外接圓] 10439 - Temple of Dune
此分類上一篇:[UVA][朱劉算法] 11183 - Teen Girl Squad

是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文