2011年12月9日 星期五

d150: 11369 - Shopaholic

內容 :
    林希是個購物狂。每次只要有買二送一的折扣,她就像瘋了一樣要買下店裡所有的商品。你已經放棄治療她的病了,但是想減少她的支出。
    你知道買二送一所送的一定是結帳商品中最便宜的那幾樣。比如說,你的朋友拿了價值為400, 350, 300, 250, 200, 150, 及 100 的七樣商品到櫃枱去結帳,她就得付 1500 元。她省下了最便宜的兩樣商品的價錢,也就是 250 元。如果她分三次去結帳,她可以省下更多的錢。比如說,她先拿400, 300 和 250 的去結,第一次就可以省下 250 元。第二次她只拿 150 元的去結,沒有折扣。但是第三次她拿350, 200, 和 100 的去結,又省了 100 元,總共省下了 350 元。
    你的工作便是找出林希最多可以省多少錢。

輸入說明 :
    第一行是測試筆數 1 ≤ t ≤ 20。每筆測試有兩行輸入。第一行是林希買的商品數 1 ≤ n ≤ 20000。下一行則是這些商品的價格 1 ≤ pi ≤ 20000。

輸出說明 :
    每個測試,輸出一行,印出如果林希適當地分次結帳時所能省下的最大金額。

範例輸入 :
1
6
400 100 200 350 300 250

範例輸出 :
400

出處 :
    UVa ACM 11369

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

#define SWAP(x,y) {int t; t = x; x = y; y = t;} 

void quicksort(int[], int, int, int); 

int main(void)
{ 
    int t,n,i,num[20000],ans;
    
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(i=0; i<n; i++)
            scanf("%d",&num[i]);
        quicksort(num, 0, n-1, n);
        
        ans = 0;
        for(i=2; i<n; i=i+3)
            ans+=num[i];
        printf("%d\n",ans);
    }
    return 0; 
}

void quicksort(int number[], int left, int right, int MAX)
{
    int i, j, s;
    if(left < right)
    {
        s = number[left];
        i = left;
        j = right + 1;
        while(1)
        {
            while(i + 1 < MAX && number[++i] > s) ;
         
            while(j -1 > -1 && number[--j] < s) ;
            if(i >= j)
                break;
            SWAP(number[i], number[j]);
        }
        number[left] = number[j];
        number[j] = s;
        quicksort(number, left, j-1, MAX);
        quicksort(number, j+1, right, MAX);
    } 
}


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

a291: nAnB problem

內容 :
    我們常用數字密碼鎖來保護重要的東西,但要是不小心忘了密碼麻煩就大了!
    以四位數字的密碼鎖為例,我們最多要嘗試10^4=10000次才能解鎖。這時候要是
    有辦法知道目前嘗試的密碼錯了幾個字,那解鎖的速度就快多了。請寫一個程式,
    可以判斷每組數字跟正確答案差了幾個字。

輸入說明 :
    多筆輸入。
    第一行有四個介於0-9之間的數字,代表正確的密碼
    第二行有一個整數n,1<=n<=10000,代表接下來嘗試n組密碼
    接下來有n行,每行有四個介於0-9之間的數字,每行各代表一組嘗試的密碼。

輸出說明 :
    輸出n行。
    對於每組嘗試的密碼,若有p個數字的值正確,且在正確的位子上,
    另外有q個數字的值正確,但不在正確的位子上,
    輸出pAqB。
    範例見測資。

範例輸入 :
1 2 3 4
4
1 1 4 5
1 2 4 3
1 1 4 4
4 3 2 1

1 1 1 5
4
1 1 1 1
0 9 2 8
1 5 2 3
1 1 5 1

範例輸出 :
1A1B
2A2B
2A0B
0A4B
3A0B
0A0B
1A1B
2A2B

程式碼 :
#include<stdio.h>
int main()
{
    int a,b,i,j,n,ans[4],input[4],check[4];
    while(scanf("%d %d %d %d",&ans[0],&ans[1],&ans[2],&ans[3])==4)
    {
        scanf("%d",&n);
        while(n--)
        {
            a = b = 0;
            for(i=0; i<4; i++)
            {
                scanf("%d",&input[i]);
                if(ans[i] == input[i])
                {
                    a++;
                    check[i] = 1;
                }
                else
                    check[i] = 0;
            }
            for(i=0; i<4; i++)
                if(check[i] != 1)
                    for(j=0; j<4; j++)
                        if(check[j]==0 && (input[i] == ans[j]) && j!=i)
                        {
                            b++;
                            check[j] = 2;
                            break;
                        }
            printf("%dA%dB\n",a,b);
        }
    }
    return 0;
}




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

2011年12月8日 星期四

d481: 矩陣乘法

內容 :
    矩陣相乘最重要的方法當然是一般矩陣乘積了,它只有在第一個矩陣的列數 (column)和第二個矩陣的行數(row)相同時才有定義。一般單指矩陣乘積時,指的便是 一般矩陣乘積。若 A 為 m×n 矩陣,B 為 n×p 矩陣,則他們的乘積 AB(有時記做A · B)會是 一個 m×p 矩陣。其乘積矩陣的元素如下面式子得出:

 

    以上是用矩陣單元的代數系統來說明這類乘法的抽象性質。

    由定義直接計算

Matrix multiplication diagram.PNG左邊的圖表示出要如何計算 AB 的 (1,2) 和 (3,3) 元素,當 A 是個 4×2 矩陣和 B 是個 2×3 矩陣時。分別來自兩個矩陣的元素都依箭頭方向而兩兩配對,把每一對中的兩個元素相乘,再把這些乘積加總起來,最後得到的值即為箭頭相交位置的值。

    內容來源:矩陣乘法

(AB)_{1,2} = \sum_{r=1}^2 a_{1,r}b_{r,2} = a_{1,1}b_{1,2}+a_{1,2}b_{2,2}
(AB)_{3,3} = \sum_{r=1}^2 a_{3,r}b_{r,3} = a_{3,1}b_{1,3}+a_{3,2}b_{2,3}

    每組測資有 2 個矩陣,請把他們相乘之後的結果輸出

輸入說明 :
    輸入數據不會超過 231-1
    兩矩陣大小不超過 100 * 100
    每組測資第一行四個數字 a b c d
    代表第一個矩陣有 a 列 b 行
            第二個矩陣有 c 列 d 行
    接下來 a 行,每行 b 個數字
                 c 行,每行 d 個數字
    每個數字以空白隔開
    不懂請參考範例輸入

輸出說明 :
    輸出相乘之後的矩陣
    每個數字以空白隔開
    兩矩陣不能相乘請輸出Error再換下一組測資(不用讀取矩陣)

範例輸入 :
3 2 2 3
1 2
3 4
5 6
1 2 3
4 5 6
1 2 3 4

範例輸出 :
9 12 15
19 26 33
29 40 51
Error

程式碼 :
#include<stdio.h>

int main()
{
    int a,b,c,d,i,j,k,temp;
    long long data1[100][100],data2[100][100],ans[100][100];
    
    while(scanf("%d %d %d %d",&a,&b,&c,&d)==4)
    {
        if(b != c)
            printf("Error\n");
        else
        {
            for(i=0; i<a; i++)
                for(j=0; j<b; j++)
                    scanf("%lld",&data1[i][j]);
            for(i=0; i<c; i++)
                for(j=0; j<d; j++)
                    scanf("%lld",&data2[i][j]);
            
            for(i=0; i<a; i++)
                for(j=0; j<d; j++)
                {
                    ans[i][j] = 0;
                    for(k=0; k<b; k++)
                        ans[i][j]+=data1[i][k]*data2[k][j];
                }
            
            for(i=0; i<a; i++)
            {
                for(j=0; j<d; j++)
                    printf("%lld ",ans[i][j]);
                printf("\n");
            }
        }
    }
    
    return 0;
}




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