24h購物| | PChome| 登入
2012-10-03 08:39:14| 人氣704| 回應1 | 上一篇 | 下一篇

[PTC][201209] ABCE 爛解

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

Background
PTC 噩夢啊, 比賽過一個小時後, 我才從通識回來 ... 最終結果 4 題, 好不容易看懂 pD 的繁瑣英文, 我悲摧的來不及寫完, 還在 compile, 時間已經抵達終點 ! 神啊, 請再給我一個小時



Problem A
題意很簡單, 先給定平面 n 個點 (POI),然後對每個詢問集輸出, 有多少"次"的 POI 在詢問集的半徑內, 首先先看 n ≦ 100,0000, 直覺告訴我們 O(n*m) 是不可能通過的, 聽 inker 賽後說道這題應該是有一篇論文(
range query)的寫法, 當然比賽的時候不可能會想那麼多, 猶豫就輸了。還是 O(n*m) 下吧

#include <stdio.h>
using namespace std;
typedef struct {
    long long x, y;
} Pt;
Pt P[1000005], Q[1000005];
int main() {
    int n, i, j, m;
    long long d;
    while(scanf("%d", &n) == 1) {
        int tn = 0;
        for(i = 0; i < n; i++) {
            scanf("%lld %lld", &P[i].x, &P[i].y);
        }
        while(scanf("%d %lld", &m, &d) == 2) {
            if(m == 0 && d == 0)    break;
            for(i = 0; i < m; i++)
                scanf("%lld %lld", &Q[i].x, &Q[i].y);
            int ans = 0;
            for(i = 0; i < n; i++) {
                for(j = 0; j < m; j++) {
                    if((P[i].x-Q[j].x)*(P[i].x-Q[j].x)
                       + (P[i].y-Q[j].y)*(P[i].y-Q[j].y)
                       <= d*d) {
                       ans++;
                    }
                }
            }
            printf("%d\n", ans);
        }
    }
    return 0;
}


Problem B

簡單的去重問題, 求真正存在的使用者個數

#include <iostream>
#include <cstdio>
#include <set>
using namespace std;

int main() {
    int t;
    char in[50];
    scanf("%d", &t);
    gets(in);
    while(t--) {
        set<string> Q;
        while(gets(in)) {
            if(in[0] == '-')    break;
            Q.insert(in);
        }
        printf("%d\n", Q.size());
    }
    return 0;
}


Problem C
這題會給定一個遞增的序列, 然後挑兩項當做費式數列的首兩項, 然後看最多能再這個序列裡面湊到最多的費式數列, 有人會想說用動態規劃 DP, 直觀想是 O(n*n), 有點類似 LIS 的建法, 那當然也可以, 不過窮舉也是差不多的速度, 差不多是 O(n*n*k), 但是 k 肯定是很小的, 因為以最小的費式數列, k 也頂多 25, 而且窮舉可以剪枝, 說不定比 DP 還快。

#include <stdio.h>
int main() {
    int t;
    int i, j, n, x, f0, f1;
    scanf("%d", &t);
    while(t--) {
        scanf("%d", &n);
        int f[100000] = {};
        int a[50005];
        for(i = 0; i < n; i++) {
            scanf("%d", &a[i]);
            f[a[i]] = 1;
        }
        int ans = 2;
        for(i = 0; i < n; i++) {
            for(j = i+1; j < n; j++) {
                if(n-j+1 <= ans)
                    break;
                f0 = a[i], f1 = a[j];
                int cnt = 2;
                while(1) {
                    x = f0+f1;
                    f0 = f1;
                    f1 = x;
                    if(x > a[n-1] || f[x] == 0)
                        break;
                    cnt++;
                }
                if(cnt > ans)   ans = cnt;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}


Problem E
給一個條件的遞歸圖形, 專有名稱應該是「碎形」, 然後問一個點在幾個長方形中, 那麼直觀的遞迴找出所有長方形, 然後去判斷是否在裡面就好了, 有一題很像的在 UVa, 如果我沒記錯題目應該是「All Square」

#include <stdio.h>

int k, n, m, ans;
void dfs(int x, int y, int k) {
    if(k == 0)
        return ;
    if(x-2*k <= n && x+2*k >= n && y-k <= m && y+k >= m)
        ans++;
    dfs(x+2*k, y+k, k/2);
    dfs(x+2*k, y-k, k/2);
    dfs(x-2*k, y+k, k/2);
    dfs(x-2*k, y-k, k/2);
}
int main() {
    while(scanf("%d %d %d", &k, &n, &m) == 3) {
        if(k == 0 && n == 0 && m == 0)
            break;
        ans = 0;
        dfs(1024, 1024, k);
        printf("%d\n", ans);
    }
    return 0;
}


總結 :
這次題目難的可以很難, 不過我想出題教授應該沒有考慮的測試機器的效率, 導致濫做法可以通過, 晚了一個小時, 因此沒解出 pD, 時間上看完題目就耗費了我 30 分鐘, 英文很菜的, 很多題目看不是很懂, 單字量也不夠, 都是拿之前的解題感覺猜測題目想要求我們做些什麼。

一次 PTC 大概有一題是難題, 然而其他題猶豫就輸了, 不仿拿出不合理的複雜度去嘗試吧

台長: Morris
人氣(704) | 回應(1)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 不分類 | 個人分類: 資訊競賽 |
此分類下一篇:NCPC2012A String Editer
此分類上一篇:[ITSA] 17th 總解答

Huang
你好我是正為了ptc比賽苦惱的大一生,
想要透過e-mail請教一些經驗談,
不曉得方不方便>"<
2014-07-20 21:17:28
版主回應
不過我已經很久沒有參加,因此現在情況也不明白。
2014-07-21 19:27:17
是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文