2012年4月4日 星期三

d098: Stringstream運用練習(C++)

內容 :
    小明為了要保證資料傳輸的隱密性,為檔案設置了一個加密金鑰,並且將金鑰藏進了一個檔案裡。收到檔案的小風得知要解譯出他所使用的加密金鑰,必須將檔案裡所有不含非數字的單字找出,加起來就是加密金鑰。可是,要求出這個金鑰,如果自己慢慢加實在是太慢了,所以請你寫一個程式來幫助他吧!

輸入說明 :
    每組測資有一行,內含多個單字,每個單字之間會以空格作分隔(每一行的前後都有可能有空格,且分隔單字的空格可能不只一個)。

輸出說明 :
    請求出所有僅含數字的單字,並且加總後輸出。這些數字的總和不會超過2的16次方。

範例輸入 :
zerojudge萬歲
1a6f 6 65afd 15s 1sa 12 115

範例輸出 :
0
133

程式碼 :
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

void isword(char word[], int *sum)
{
    int i,len;
    
    len = strlen(word);
    
    for(i=0; i<len; i++)
        if('0' > word[i] || word[i] > '9')
            break;
    if(i == len)
        *sum += atoi(word);
}

int main()
{
    int i, j, k, sum = 0, len, len_word;
    char s[5000], check, word[1000];
    
    while(gets(s) != NULL)
    {
        len = strlen(s);
        
        for(i=k=0; i<len; i++)
        {
            if(s[i] == ' ')
            {
                word[k] = '\0';
                isword(word, &sum);
                k = 0;
            }
            else
                word[k++] = s[i];
        }
        
        word[k] = '\0';
        isword(word, &sum);
                
        printf("%d\n",sum);
        sum = 0;
    }
    
    return 0;
}



http://zerojudge.tw/ShowProblem?problemid=d098

d038: 900 - Brick Wall Patterns

內容 :
    如果我們要用常見的長度為高度兩倍的磚塊建一道磚牆,並且牆的高度為兩個單位,根據牆的長度,我們可以建出不同數量的花樣。從圖一我們可以看出:
                                               

  •     寛度為 1 單位的牆只有一種花樣—就是讓磚塊直立。
  •     長度為 2 的牆有 2 種花樣—兩個平躺的磚磈疊在一起以及兩個直立的磚塊併在一起。
  •     長度為 3 的牆有三種花樣。

    長度為 4 的牆你可以找出幾種花樣?那長度為 5 的牆呢?

    問題
    你的工作是要寫一個程式,給它牆的長度,它就算出這道牆可以有幾種花樣。

輸入說明 :
    你將程式會收到一連串的整數,一行一個,每個整數代表牆的長度。牆的最大長度為 50。

輸出說明 :
    對於每個輸入的牆長度,你要輸出這道牆的花樣數量,每個數字單獨一行。

範例輸入 :
1
2
3
0

範例輸出 :
1
2
3

提示 :
    背景知識: DP

出處 :
    UVa ACM 900

程式碼 :
#include <stdio.h>

int main(void) 
{
    int i, n;
    long long arr[51];
    
    arr[1] = 1;
    arr[2] = 2;
    for(i=3; i<51; i++)
        arr[i] = arr[i-1] + arr[i-2];
    
    while(scanf("%d",&n)==1)
    {
        if(n == 0)
            break;
        
        printf("%lld\n",arr[n]);
    }
    
    return 0;
}

http://zerojudge.tw/ShowProblem?problemid=d038

2012年4月3日 星期二

d378: 最小路徑

內容 :
    現在有一張地圖,凡是走過某一個格子,都會消耗體力,所以請你找出最少消耗體力值。
    現在老鼠在地圖的左上角,在走的時候時,所以只能往右或下走,之後要走到右下角,
    走過的點上的數字必須加總,請輸出加總的數字最小的。

    測資一 :
    0 7 8 9
    1 5 1 1
    2 4 10 0

    可以走 0 → 7 → 8 → 9 → 1 → 0       SUM = 7 + 8 +9 + 1 = 25
                 0 → 1 → 5 → 1 → 1 → 0       SUM = 1 + 5 + 1 + 1 =8
                 0 → 7 → 8 → 1 → 10 → 0     SUM = 7 + 8 + 1 + 10 = 26
.
.
    以此類推,只輸出最小值 8

    " 左上角跟右下角必為 0 "

輸入說明 :
    輸入的每第一行會有兩個數字 N, M ( 2 ≦ N , M ≦ 101)
    之後會有 N 行,每行上會有 M 個數字 G ( 1 ≦ G ≦ 20 )

輸出說明 :
    對每組地圖先輸出 "Case #%d :"
    輸出從左上走到右下最少的體力消耗

範例輸入 :
3 4
0 7 8 9
1 5 1 1
2 4 10 0
2 2
0 1
1 0

範例輸出 :
Case #1 :
8
Case #2 :
1

提示 :
DP

程式碼 :
#include<stdio.h>

int main()
{
    int i,j,n,m,count;
    int map[101][101];
    
    count = 1;
    while(scanf("%d%d",&n,&m)==2)
    {
        for(i=0; i<n; i++)
            for(j=0; j<m; j++)
                scanf("%d",&map[i][j]);
        
        for(i=1; i<n; i++)
            map[i][0] += map[i-1][0];
        
        for(j=1; j<m; j++)
            map[0][j] += map[0][j-1];
        
        for(i=1; i<n; i++)
            for(j=1; j<m; j++)
            {
                if(map[i-1][j] > map[i][j-1])
                    map[i][j] += map[i][j-1];
                else
                    map[i][j] += map[i-1][j];
            }
        
        printf("Case #%d :\n%d\n",count++,map[n-1][m-1]);
    }
    
    return 0;
}



http://zerojudge.tw/ShowProblem?problemid=d378

d632: C and S ??

內容 :
    有一天,小明在網路上看到一種神奇的魔法
    根據小明的推測,這種魔法似乎是一種數學布林函數
    這個函數是長這樣的:

    輸入部分:
        A、B和C
    輸出部分:
        S 和 C'

    S = A xor B xor C
    C' = (A and B) or (B and C) or (C and A)
    小明將好多個這種函數當成丸子般串起來

    並且把兩個布林數列代進去
    神奇的事情發生了...
    當A為0010
        B為0011
    所得到的S數列竟然是0101!!!
    //==================
    小明今天想做實驗,看看代入不同的A和B,所得到的S數列是長什麼樣子

輸入說明 :
    給定兩個數列A和B(AB兩者長度皆為32)

輸出說明 :
    S數列

範例輸入 :
00000000000000000000000000001100
00000000000000000000000000001101

範例輸出 :
00000000000000000000000000001100
00000000000000000000000000001101
---------------------------------
00000000000000000000000000011001
****End of Data******************

程式碼 :
#include<stdio.h>

int main()
{
    int i,carry;
    char a[33],b[33],s[33];
    char line[34] = "---------------------------------";
    char end[34] = "****End of Data******************";
    
    while(scanf("%s%s",a,b)==2)
    {
        for(i=0; i<32; i++)
        {
            a[i] -= '0';
            b[i] -= '0';
        }
        
        carry = 0;
        for(i=31; i>-1; i--)
        {
            s[i] = a[i] ^ b[i] ^ carry;
            carry = (a[i] & b[i]) | (b[i] & carry) | (a[i] & carry);
        }
        s[32] = '\0';
        
        for(i=0; i<32; i++)
        {
            a[i] += '0';
            b[i] += '0';
            s[i] += '0';
        }
        printf("%s\n%s\n%s\n%s\n%s\n", a, b, line, s, end);
    }
    
    return 0;
}


http://zerojudge.tw/ShowProblem?problemid=d632

d807: 方方

內容 :
    在一個遙遠的國度裡,每個村莊都是長方型的,雖然有時候會很不方便
    但是大家還是過著快樂的日子。直到有一天,有個異地來的軍隊,想要佔領各個村莊
    他們佔領的方式是,從村莊裡頭,切出一個儘可能大的正方形,先佔為己有
    隔日,在從未佔領的部分,重複這樣的動作。
    直到某一天,未佔領的部分為一個正方形的時候,就結束佔領的動作。
    現在我們想知道,最後的那一個正方形是多大?(見圖)
 

輸入說明 :
    給定兩個正整數 n,m 表示村莊的長寬。n,m皆介於 1 ~ 10^9
    包含多筆測試資料。

輸出說明 :
    輸出,最後的正方形大小

範例輸入 :
5 5
2 1
2 2
10 5
13 9

範例輸出 :
5
1
2
5
1

PS : 最大公因數

程式碼:
#include<stdio.h>

int main()
{
    int m,n;
    
    while(scanf("%d%d",&m,&n)==2)
    {
        if(m < n)
            m ^= n ^= m ^= n;
        while((m = (m % n)) != 0)
        {
            m ^= n ^= m ^= n;
        }
        printf("%d\n",n);
    }
    
    return 0;
}




http://zerojudge.tw/ShowProblem?problemid=d807