ACM-ICPC 2012 国内予選 Problem C 偏りのあるサイコロ

偏りのあるサイコロ

#include <iostream>
#include <vector>
#include <cstdlib>
using namespace std;

//  サイコロDを回転したサイコロを返す
vector<int> spin( vector<int> D, int dir )
{
    vector<int> R;
    int T[4][6] = {
        { 3, 0, 2, 5, 4, 1 },
        { 4, 1, 0, 3, 5, 2 },
        { 1, 5, 2, 0, 4, 3 },
        { 2, 1, 5, 3, 0, 4 } };
    for ( int i=0; i<6; i++ )
        R.push_back(D[T[dir][i]]);
    return R;
}

int main()
{
    while ( true )
    {
        int n;  cin>> n;
        if( n==0 )
            break;

        const int W = 256;
        vector<vector<int> > H(W,vector<int>(W));   //  高さ
        vector<vector<int> > F(W,vector<int>(W));   //  上面の目

        for ( int i=0; i<n; i++ )
        {
            int t, f;  cin>>t>>f;

            //  適当に転がせば、上面がtで前面がfのサイコロになるはずw
            int D_[] = { 1, 3, 5, 4, 2, 6 };
            vector<int> D(D_,D_+6);
            while ( D[0]!=t || D[1]!=f )
                D = spin(D,rand()%4);

            int px = W/2;
            int py = W/2;

            while ( true )
            {
                int dx[] = {0,1,0,-1};
                int dy[] = {1,0,-1,0};
                int dir = -1;

                for ( int d=0; d<4; d++ )
                {
                    if ( D[d+1]>=4 &&
                         H[px+dx[d]][py+dy[d]] < H[px][py] )
                    {
                        if ( dir==-1 || D[dir+1]<D[d+1] )
                            dir = d;
                    }
                }
                if ( dir == -1 )
                    break;
                D = spin(D,dir);
                px += dx[dir];
                py += dy[dir];
            }

            H[px][py]++;
            F[px][py] = D[0];
        }

        int c[7] = { 0};
        for ( int x=0; x<W; x++ )
        for ( int y=0; y<W; y++ )
            c[F[x][y]]++;
        for ( int i=1; i<=6; i++ )
            cout << (i==1?"":" ") << c[i];
        cout << endl;
    }

    return 0;
}