Hatena::Grouptopcoder

れんしゅうちょう。 このページをアンテナに追加 RSSフィード

 | 

2012-07-07ICPC2012国内予選

[]ICPC2012国内予選 18:38

ICPC国内予選に, misawa2012として出た. 締め切り数時間前に登録するというアレっぷりであった.

http://www.cs.titech.ac.jp/icpc2012/domestic-contest-result.html

http://imoz.jp/icpc/2012-domestic.html

38位だったっぽくて, ギリギリ次行けるっぽい. 公式の発表はまだっぽいけれど. とりあえず, 忘れないうちに書いておこうと.

A→B→C→E(解けてない)の順に取りかかった. 問題はここに. 結局問題文通りにやればよい問題しか解けてないのである.


A問題

基本的にやるだけな問題であるが, どう解くかがキーであると思う. 方針に依って, バグ混入のしやすさや, タイピング量が違うだろうなぁと.

良かった点:
O(1)を書こうとせずに, ちゃんと自明なぶん回し方向を目指した.

反省点:
3年飛ばしなどやる必要無い.
こんだけのを書くのにどんだけバグらせたのか.
月日を0ベースにするのか1ベースにするのかの決断が遅すぎる. 曖昧に書き始めないで, 意識するべき.
llにするべきか, 確かめずにintにしていた. サンプル入力で最大ケースが出ていて, intで良いことをちゃんと確かめるか, llにするべきだった.

#include <iostream>

using namespace std;

int N;

void pre(){
    N = 5 * 39 * 2 + 20 * 10;
    return;
}

int solve(int y, int m, int d){
    int res = 0;
    while(y+3 < 1000){
        res += N;
        y += 3;
    }
    while(y < 1000){
        while(m <= 10){
            while(d <= 19 + (m%2)){
                ++res;
                ++d;
            }
            if(y%3 == 0 && m%2 == 0) ++res;
            d = 1;
            ++m;
        }
        m = 1;
        ++y;
    }
    return res;
}
int main(void){
    pre();
    int n;
    cin >> n;
    for(int i=0; i<n; ++i){
        int y, m, d;
        cin >> y >> m >> d;
        cout << solve(y, m, d) << endl;
    }
}

B問題

これも基本的にはやるだけ. stringでやるかとかで差が出るかもしれない. 出力する物を見誤って, 1WAした.

良かった点:
全部llにした. 入力的に大丈夫であっても, 安心感が違う.
関数に分けた点. デバッグがしやすい.
出力の±1とかの定数誤差をちゃんと考えずに, サンプルで修正した. 良くも悪くもあるが, この問題ではこれで良い.

反省点:
サンプル出力は目diffではなく, ちゃんとdiffを取れ.
使う変数名は統一しろ. 今回なら, どの関数でも桁数はdを使うとかするべき.

#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <map>

using namespace std;

typedef vector<int> vi;
typedef long long ll;


#define rep(i, n) for(int i=0; i<(n); ++i)

#define pb push_back
#define all(v) v.begin(), v.end()

vi f(ll n, ll k){
    vi res;
    rep(i, k){
        res.pb(n%10);
        n/=10;
    }
    return res;
}

ll next(ll x, ll n){
    vi hoge = f(x, n);
    sort(all(hoge));
    ll small = 0, large = 0;
    rep(i, n){
        small *= 10;
        large *= 10;
        large += hoge[hoge.size()-i-1];
        small += hoge[i];
    }
    return large - small;
}

int main(void){
    ll n, k;
    while(true){
        map<ll, ll> x;
        cin >> n >> k;
        if(!(n|k)) break;
        ll res = 0;
        while(!x.count(n)){
            x[n] = res;
            ++res;
            n = next(n, k);
        }
        cout << x[n] << " " << n << " " << -x[n]+res << endl;
    }
}

C問題

サイコロライブラリゲー. すぱげそーす様様である. サイコロが作れれば, 後はルール通りに転がしていけば良い.

良かった点:
スパゲソースちゃんと印刷していった.

反省点:
tとfからダイスを作る時, 乱択で適当にぶんまわせば出来るだろ的発想は良かったが, 他の所でバグらせて使わなかった. むしろ全パターンをsetとかで持っておけば楽だったハズである.
ちゃんとライブラリ使った事が無かった. 使えるようにしておかないといけない.
0ベースと1ベースの違いでバグらせすぎ.
foreachが死んでる.
ネスト深くなり, 行数も伸び, 対応する括弧が画面に収まらないようなループや場合分けを作るべきではない. 関数分けしろ. これのせいでかなり時間を食った. 関数分けする時間<<バグフィックスする時間*バグ出す確率

#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <map>

using namespace std;

typedef vector<int> vi;
typedef long long ll;


#define rep(i, n) for(int i=0; i<(n); ++i)
#define foreach(it, v) for(typeof(v)::iterator it = (v).begin(); it != (v).end(); ++it)
#define mp make_pair

#define pb push_back
#define all(v) v.begin(), v.end()
typedef pair<int, int> pii;

enum FACE{
    TOP, BOTTOM, FRONT, BACK, LEFT, RIGHT
};
template<class T>
class dice{
    public:
        dice(){
            id[TOP] = 0;
            id[FRONT] = 2;
            id[LEFT] = 1;
            id[RIGHT] = 4;
            id[BACK] = 3;
            id[BOTTOM] = 5;
        }
        T& operator[](FACE f){ return var[id[f]];}
        const T& operator==(const dice<T> &b) const{
            const dice<T> &a = *this;
            return a[TOP] == b[TOP] && a[BOTTOM] == b[BOTTOM] && a[FRONT] == b[FRONT] && a[BACK] == b[BACK] && a[LEFT] == b[LEFT] && a[RIGHT] == b[RIGHT];
        }
        void roll_x(){ roll(TOP, BACK, BOTTOM, FRONT);}
        void roll_x2(){ roll(TOP, FRONT, BOTTOM, BACK);}
        void roll_y(){ roll(TOP, LEFT, BOTTOM, RIGHT);}
        void roll_y2(){ roll(TOP, RIGHT, BOTTOM, LEFT);}
        void roll_z(){ roll(FRONT, RIGHT, BACK, LEFT);}

        vector<dice> all_rolles(){
            vector<dice> ret;
            for(int k=0; k<6; (k&1?roll_y():roll_x()), ++k)
                for(int i=0; i<4; roll_z(), ++i)
                    ret.push_back(*this);
            return ret;
        }
        void roll(FACE a, FACE b, FACE c, FACE d){
            T tmp = id[a];
            id[a] = id[b];
            id[b] = id[c];
            id[c] = id[d];
            id[d] = tmp;
        }
        T var[6];
        int id[6];
};


dice<int> get_dice(int t, int f){
    dice<int> res;
    if(res.id[TOP] != t){
        if(res.id[BOTTOM] == t) res.roll_x();
        while(res.id[FRONT] != t) res.roll_z();
        res.roll_x2();
    }
    while(res.id[FRONT] != f) res.roll_z();
    return res;
}

int main(void){
    ll n;
    while(true){
        cin >> n;
        map<pii, int> height;
        map<pii, int> top;
        if(!n) break;
        rep(dicessss, n){
            //cout << "dice #" << dicessss << endl;
            int t, f;
            dice<int> d;
            int x = 0, y = 0;
            cin >> t >> f;
            --t;
            --f;

            d = get_dice(t, f);

            //height[mp(0,  0)] = 0;
            while(true){
                FACE sokumen[] = {FRONT, BACK, LEFT, RIGHT};
                int dx[4] = {1, -1, 0, 0};
                int dy[4] = {0, 0, 1, -1};
                int mx = -1;
                FACE to;
                rep(i, 4){

                    if(!height.count(mp(x+dx[i], y+dy[i])))
                        height[mp(x+dx[i], y+dy[i])] = 0;
                    if(d.id[sokumen[i]] > mx && height[mp(x+dx[i], y+dy[i])] < height[mp(x,y)]){
                        to = sokumen[i];
                        mx = d.id[sokumen[i]];
                    }
                }
                if(mx <= 2) break;
                if(to == FRONT){
                    //cout << "FRONT" << endl;
                    d.roll_x();
                    x += 1;
                }
                if(to == BACK){
                    //cout << "BACK" << endl;
                    d.roll_x2();
                    x -= 1;
                }
                if(to == LEFT){
                    //cout << "LEFT" << endl;
                    d.roll_y2();
                    y += 1;
                }
                if(to == RIGHT){
                    //cout << "RIGHT" << endl;
                    d.roll_y();
                    y -= 1;
                }
            }
            //cout << x << ", " << y << ": "<< d.id[TOP] << endl;
            height[mp(x,y)]++;
            top[mp(x,y)] = d.id[TOP];
        }
        int res[6] = {0};
        for(map<pii, int>::iterator it = top.begin(); it != top.end(); ++it){
            res[it->second]++;
            // cout << it->first << ", " << it2->first << ": " << it2->second << endl;
        }
        rep(i, 5){
            cout << res[i] << " ";
        }
        cout << res[5] << endl;
    }
}
 |