20111015

ACM 10257 Dick and Jane

n歲的定義:過了n歲的生日,但還沒過n+1歲的生日,這個期間,都是n歲。

由題目可知
(1)Spot s歲時,Puff出生。
(2)Puff p歲時,Yertle出生。
(3)Spot y歲時,Yertle出生。
(4)Dick + Jane = Spot + Puff + Yertle
由(1)(2)(3)可知大小順序: Spot > Puff > Yertle。

以年紀最小的Y往上推:
(a)當Y x歲時,P為 x+p歲或 x+p + 1歲。
(b)當Y x歲時,S為 x+y歲或 x+y + 1歲。

由(a)(b)可得總歲數sum的所有可能情況:
x + (x+p) + (x+y)
x + (x+p) + (x+y+1)
x + (x+p+1) + (x+y)
x + (x+p+1) + (x+y+1)

由sum求x:
sum = 12(d歲) + j歲 = 3x + p + y + (0or1or2)
x = [(12+j) - p - y - (0or1or2)] / 3
以下分別解釋每種情況。

第一種:x = [(12+j) - p - y - 0] / 3
歡樂解,直接輸出S、P、Y的年齡:x+y、x+p、x

第二種:x = [(12+j) - p - y - 1] / 3
(12+j) - p - y要減1之後才能被3整除,
所以用3對(12+j) - p - y取餘數,一定餘1。
餘1的情況有兩種:S+1或P+1。
由(a)(1)可以推導出
(c)當P x+p歲時  ,S為(x+p)   + s歲或(x+p)   + s + 1歲。
(d)當P x+p+1歲時,S為(x+p+1) + s歲或(x+p+1) + s + 1歲。

(d)是P+1的情況,所以(c)一定是S+1,把兩式化簡再跟(b)做比較:

(c)當P x+p歲時  ,S為(x+p) + s + 1 = x+y+1
(d)當P x+p+1歲時,S為(x+p+1) + s   = x+y
刪x
(c)當P x+p歲時  ,S為p + s + 1 = x+y+1
(d)當P x+p+1歲時,S為p+1 + s   = x+y 
最後可得
(c)p + s = y
(d)p + s + 1 = y
所以判斷p + s是否等於y,就能知道是S+1或P+1。

第三種:x = [(12+j) - p - y - 2] / 3
減2才能被3整除,所以用3對(12+j) - p - y - 2取餘數
會餘2。即S、P要各+1再輸出。

打字好多好累 -_-|
簡單講,就是Y x歲生日時,S跟P可能生日過了(各+1),
或是其中一個過了(S+1 or P+1),或是都還沒過。
/**
/* ACM 10257
 * mythnc
 * 2011/10/15 20:11:27   
 * run time: 0.004
 */
#include <stdio.h>

int main(void)
{
    int s, p, y, j, x; /* x: Yertle's age */

    while (scanf("%d %d %d %d", &s, &p, &y, &j) == 4) {
        x = (12 + j - p - y) / 3;
        switch((12 + j - p - y) % 3) {
            case 0:
                printf("%d %d %d\n", x + y, x + p, x);
                break;
            case 1:
                if (s + p == y)
                    printf("%d %d %d\n", x + y + 1, x + p, x);
                else
                    printf("%d %d %d\n", x + y, x + p + 1, x);
                break;
            case 2:
                printf("%d %d %d\n", x + y + 1, x + p + 1, x);
                break;
        }
    }
    return 0;
}

沒有留言: