備忘録

まとめておきたいことのメモ 主にプロコンのこと

AOJ-ICPC 1179

今回はこの問題。

Millennium | Aizu Online Judge

新たな暦を用いて1000年目だし、自分の誕生日から1000年1月1日まで何日あるのか数えるプログラムを作ろう、という問題。
この新たな暦では、1年は10ヶ月からなります。月にはbig month とsmall monthの2種類があり、前者は20日、後者は19日で、1年はbig monthから始まります。ただし3年、6年、9年、…と3の倍数の年は10ヶ月とも全部big monthになっています。

では解答を。

#include <cstdio>
#include <iostream>
#include <cmath>
#include <ctype.h>
#include <string> 
#include <sstream>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <map>
#include <queue>
#include <utility>
#include <vector>
#include <set>
  
using namespace std;
 
int count(int y, int m, int d);
 
int main()
{
    int n, year, month, date;
    cin >> n;
    for(int i = 0; i < n; i++){
        cin >> year >> month >> date;
        cout << count(year, month, date) << endl;
    }
   return 0;
}
 
int count(int y, int m, int d)
{
    int ans = 0;
    for(int i = y + 1; i < 1000; i++){
        if(i % 3 == 0) ans += 10 * 20;
        else ans += 5 * 20 + 5 * 19;
    }
    for(int i = m + 1; i <= 10; i++){
        if(y % 3 == 0) ans += 20;
        else {
            if(i % 2 == 1) ans += 20;
            else ans += 19;
            }
    }
    if(m % 2 == 0 && y % 3 != 0) ans += 19;
    else ans += 20;
    ans -= d - 1;
    return ans;
}

日数を出すための関数countを作りました。
誕生年の次の年から999年まで、3の倍数かどうかで分けて一年単位で日数をansに加えます。
それから誕生月の次の月から10月まで日数を足していきます。ここでは年が3の倍数になっているかどうかと、その月はbig monthなのかsmall monthなのか分けて加えていきます。
それから日にちを微調整()しておしまい。


ところで私は以前この問題を解いたことがあるのですが、そのときの解答がこちらです。

#include <cstdio>
#include <iostream>
#include <cstdlib>
 
using namespace std;
 
int func(int y, int m, int d);
 
int main()
{
    int w;
    w = func(1000,1, 1);
    int n;
    cin >> n;
    for(int i = 0; i < n; i++){
        int y, m, d, x, z;
        cin >> y >> m >> d;
        x = func(y, m, d);
        z = w - x;
        cout << z << endl;
    }
}
 
int func(int y, int m, int d)
{
    int a, b, c;
    a = y - 1;
    a = ((2 * (a / 3) ) + a % 3)  * (20 * 5 + 19 * 5) +(a / 3) * (20 * 10);
    b = m - 1;
    if(y % 3 == 0) b = b * 20;
    else b = (b / 2 + b % 2) * 20 + (b / 2) * 19;
    c = a + b + d;
    return c; 
} 

こちらでは日数を計算するのにfor文を使っていません。
そのため行数が少なくすっきりとしていますが、やってることがわかりやすいのは今回書いた方じゃないのかなあ。
で、気になったのが実行にかかった時間。
for文を用いている方が時間がかかりそうにみえたのですが、どちらもCPU Timeは00.00secでした。
もっと差がつくと思ってたのですが意外。
testcaseの数が増えたりすると時間も変わってくるのかしら。そのあたりもまた勉強しないといけないかな。