1. 程式人生 > >NOIP2007 提高組 題解

NOIP2007 提高組 題解

com 想是 設有 最長路徑 區間 space 輸出 als ons

2007 提高組題解

第一題 一開始還想是不是要用哈希表儲存呢,但仔細想了一會兒,那個數據量20W 用個快排序,時間是能過的。所以這道題用個STL的快排,再一個循環統計個數就OK了。但最後交上去評測時0分,很尷尬。就是我在數據初始化時從一開始計數,我循環又從一開始,你懂的,多算了一次,爆掉了。改了就100了。200W的話數據就很強了,用哈希好一些。

第二題 額,寫得很快,果然這種無腦模擬題最適合我了。但自信沒檢查,帶了3組給的數據就走了。果然錯了,過了4個點好像。主要是題沒讀完,沒有判斷處於字母和數字的情況,然後輸出了一堆亂七八糟的字符,嗯,爆了。完了之後9分,哇,好氣啊。再核對了一遍數據,額,我處理轉大寫時是這樣寫的:/* buffer – ‘a’+ ‘A’*/ 帶數字進去可想而知是什麽鬼了,我開始看數據時是‘3’變為了 ! 我還以為是十進制變成了十六進制呢。= =

第三題 處理了前60% 的數據,但答案沒有高精,40分。聽了orange Lee 的類的高精度處理講解後,有了那麽點感覺,但還是很不熟悉,這種果然還是要平時多寫,其實主要是不怎麽喜歡高精,感覺數組處理起來很煩,能用Long long 的題就是好題。總的來說是一道區間DP,主要難點還是高精的處理上。

第四題 做了半天也就不想做了,加上讀了半天題沒讀懂很心累。其實是Floyd算法求直徑,然後根據情況來選取偏心距。

/*

首先來考慮只有一條直徑的時候,後面會說明有多條直徑的時候可以當作一條來處理。首先可以通過經典的O(n)的算法求出樹上的最遠點,即一條直徑(做法是從任意一點開始DFS一次求出一個最遠的點,這是直徑的一個端點;再從這個最遠點開始再次DFS,再找到的最遠點就是直徑的另外一個端點)。然後順序枚舉這條最長路徑上的每條長度小於s的最長子路徑(說不太清楚看代碼吧...),用一個隊列維護。這樣每一條可能的路徑就是一個可能的核,再求出對應的偏心距就可以了。我是先用了一個Floyd預處理出所有頂點之間的最點路備用。 ok,來說有多條直徑的問題: 題目中已經說了,如果有多條直徑的話他們的中心也一定重合,換言之一定至少有一個節點或一條路徑重合。假設有兩條直徑分別為AB和CD,它們重合的部分是EF。那麽一定有AE的長度等於CE的長度,FB的長度等於FD的長度。其次核一定是在直徑的中央部分。下面分兩種情況討論: 1. 如果給定的s能夠覆蓋重合的點或者路徑,那麽我們在任一條直徑上選擇一個核,那麽對於另外的直徑而言,就是只選擇了重合的部分,對於這個核的偏心距“有貢獻”的只可能是在非選中的直徑上,而對於每條直徑除去重合部分剩下的兩部分的長度都是相等的,所以選擇任意一條直徑均可。 2. 如果不能覆蓋,那麽對於所有直徑選擇的部分都是相同的了,更是可以任選了。 兩點還可以改進的地方,由於數據不是很強,我也就沒改: 1. 核一定是在直徑的中央部分,所以可以從直徑的中心向兩邊擴展求核。 2. 距離核最遠的點一定是度為1的點,Floyd預處理有點浪費了。

*/

#include<iostream>
#include<algorithm>
using namespace std;
int data[200010];
int n,comp,tot;
int main()
{
    freopen("count.in","r",stdin);
    freopen("count.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&data[i]);
    sort(data+1,data+n+1);
    comp 
= data[1]; tot = 1; for(int i=2;i<=n;i++){ if(comp == data[i]) tot++; else { printf("%d %d\n",comp,tot); comp = data[i]; tot = 1; } } printf("%d %d\n",comp,tot); return 0; }

#include<iostream>
#include<cstring>
using namespace std;
int p1,p2,p3;
char str[110];
int main()
{
    freopen("expand.in","r",stdin);
    freopen("expand.out","w",stdout);
    cin >> p1 >> p2 >> p3;
    cin >> str;
    int lenth = strlen(str);
    for(int i=0;i<=lenth-1;i++){
        if(str[i] == - && str[i-1] < str[i+1]){
            if(p3 == 1){
                int comp = str[i-1];
                while(++comp < str[i+1]){
                    for(int i=1;i<=p2;i++){
                        if(p1 == 1) cout << (char)comp;
                        else if(p1 == 2) cout << (char)(comp - a + A);
                        else cout << *;
                    }
                }
            }
            else {
                int comp = str[i+1];
                while(--comp > str[i-1]){
                    for(int i=1;i<=p2;i++){
                        if(p1 == 1) cout << (char)comp;
                        else if(p1 == 2) cout << (char)(comp - a + A);
                        else cout << *;
                    }
                }
            }
        }
        else {
            cout << str[i];
        }
    }
    return 0;
}

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int power=4;
const int base=10000;
const int maxl=10;
struct num
{
    int a[maxl];

    num()
    {
        memset(a,0,sizeof(a));
    }

    num operator + (const num &b)
    {
        num c;
        c.a[0] = max(a[0],b.a[0]);
        for (int i=1; i<=c.a[0]; i++)
        {
            c.a[i] += a[i]+b.a[i];
            c.a[i+1] += c.a[i]/base;
            c.a[i] = c.a[i]%base;
        }
        if (c.a[c.a[0]+1])++c.a[0];
        return c;
    }

    num operator + (const int &b)
    {
        a[1]+=b;
        int i=1;
        while (a[i]>=base)
        {
            a[i+1] += a[i] / base;
            a[i] %= base;
            i++;
        }
        if (a[a[0] + 1]) a[0]++;
        return *this;
    }

    num operator = (int b)
    {
        a[0] = 0;
        while (b)
        {
            a[0]++;
            a[a[0]] = b % base;
            b /= base;
        }
        return *this;
    }

    bool operator < (const num &b) const
    {
        if (a[0] < b.a[0]) return true;
        if (a[0] > b.a[0]) return false;
        for (int i = a[0]; i > 0; --i)
        {
            if (a[i] != b.a[i]) return a[i] < b.a[i];
        }
        return false;
    }

    void print()
    {
        printf("%d", a[ a[0] ]);
        for (int i = a[0]-1; i > 0; --i)
            printf("%0*d", power, a[i]);
        printf("\n");
    }

} ans,f[maxn][maxn];

int main()
{
//    freopen("game.in","r",stdin);
//    freopen("game.out","w",stdout);
    scanf("%d%d",&n,&m);
    for (int i=1; i<=n; i++)
    {
        for (int j=1; j<=m; j++) scanf("%d",&a[j]);
        for (int j=1; j<=m; j++) f[j][j] = a[j];
        for (int j=1; j<=m-1; j++)
        {
            for (int k=1; k<=m-j; k++)
            {
                int l = k + j;
                f[k][l] = max(f[k+1][l] + f[k+1][l] + a[k], f[k][l-1] + f[k][l-1] + a[l]);
            }
        }
        ans = ans + f[1][m];
        ans = ans + f[1][m];
    }
    ans.print();
    return 0;
}

#include<cstring>
#include<iostream>
using namespace std;
int map[350][350],deal[350];
int n,lev,x,y,value,ans = 2147483647;
int main()
{
    memset(map,127/3,sizeof(map));
    cin >> n >> lev;
    for(int i=1; i<=n; i++) map[i][i] = 0;
    for(int i=1; i<=n-1; i++)
    {
        cin >> x >> y >> value;
        map[x][y] = map[y][x] = value;
    }
    for(int k=1; k<=n; k++)
    {
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
            {
                map[i][j] = min(map[i][k] + map[k][j],map[i][j]);
            }
        }
    }
    int record = 0;
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
        {
            if(map[i][j] > record)
            {
                record = map[i][j];
                x = i;
                y = j;
            }
        }
    }
    for(int i=1; i<=n; i++)
        if(map[x][i] + map[i][y] == map[x][y]) deal[++deal[0]] = i;
    for(int i=1; i<=deal[0]; i++)
    {
        for(int j=1; j<=deal[0]; j++)
        {
            if(map[deal[i]][deal[j]] <= lev)
                ans = min(ans,max(min(map[x][deal[i]],map[x][deal[j]]),min(map[deal[i]][y],map[deal[j]][y])));
        }
    }
    cout << ans;
    return 0; 
}

NOIP2007 提高組 題解