ICPC 2012 国内予選参加記

3完 61位 予選敗退

私の学校からは始めての参加ということで、少なからず期待されていたりもしたのですが、一歩?及ばず残念な結果になってしまいました。

A

ヘンテコなカレンダーがあり、Y年M月D日から1000年1月1日までの日数を数える問題。

この手の問題が出た時には、翌月の1日→翌年の1月1日 というように、一度1月1日まで移動してから1年ずつずらす、という解き方をすることにしています。

B

怪しい数列の生成法がある。
同じ数字が2度現れることがあるので、その数字と、何項目と何項目に生成されるかを答えよ。

sstream等を利用してtoStringやtoIntをすると楽なはず。バグったりしていろいろ大変だった。

C

おかしな転がり方をするサイコロがある。とある点にいくつかのサイコロを落とすと、法則にしたがって転がっていくが、最終的には上を向いている1〜6の面はそれぞれいくつあるか。

サイコロの回転はルーズリーフを切り貼りしてシミューレーション。回転後の面の位置を手打ちしました☆(ゝω・)vキャピ

A

int main(){
	int n;
	cin>>n;
	while(n--){
		int y,m,d,cnt=0;
		cin>>y>>m>>d;
		if(y % 3 == 0) {
				cnt += (21 - d);
		}
		else {
				cnt += ((m % 2 == 0 ? 20 : 21) - d);
		}
		for(int i = m + 1; i <= 10; i++) {
				if(y % 3 == 0) {
						cnt += 20;
				}
				else{
						if(i % 2 == 0) {
								cnt += 19;
						}
						else {
								cnt += 20;
						}
				}

		}
		for(int i = y + 1; i <= 999; i++) {
				if(i % 3 == 0) {
						cnt += 20 * 10;
				}
				else {
						cnt += 20 * 5 + 19 * 5;
				}
		}
		cout<<cnt<<endl;
	}
	return 0;
}

B

int toInt(const string &s) {
	istringstream is(s);
	int N; is >> N;
	return N;
}

string toString(int num, int L) {
	int len = log10(num) + 1;
	ostringstream os;
	for(int i = 0; i < L - len; i++)
		os << "0";
	os << num;
	return os.str();
}

int main() {
	for(int a, l; cin >> a >> l, a || l;) {
		map<int, int> m;
		m[a] = 0;
		int ansi = -1, ansj = -1;
		int ans = -1;
		for(int i = 1; i <= 20; i++) {
			string s = toString(a, l);
			sort(s.begin(), s.end());
			int minv = toInt(s);
			sort(s.rbegin(), s.rend());
			int maxv = toInt(s);
			int next = maxv - minv;
			if(m.count(next)) {
				ansj = m[next];
				ansi = i;
				ans = next;
				break;
			}
			else {
				m[next] = i;
			}
			a = next;
		}
		cout << ansj << " " << ans << " " << ansi - ansj << endl;
	}
}

C

const int side[6][6] = {
	{-1, 3, 5, 2, 4, -1},
	{4, -1, 1, 6, -1, 3},
	{2, 6, -1, -1, 1, 5},
	{5, 1, -1, -1, 6, 2},
	{3, -1, 6, 1, -1, 4},
	{-1, 4, 2, 5, 3, -1}
};

const int rotation[4][6] = {
	{1, 5, 2, 0, 4, 3},
	{2, 1, 5, 3, 0, 4},
	{3, 0, 2, 5, 4, 1},
	{4, 1, 0, 3, 5, 2}
};

struct Dice {
	int num[6];
	Dice(int top, int front) {
		num[0] = top;
		num[1] = front;
		num[2] = side[top - 1][front - 1];
		num[3] = 7 - front;
		num[4] = 7 - num[2];
		num[5] = 7 - top;
	}

	void rotate(int dir) {
		dir--;
		int cp[6];
		for(int i = 0; i < 6; i++)
			cp[i] = num[i];
		for(int i = 0; i < 6; i++) {
			num[rotation[dir][i]] = cp[i];
		}
	}
};

int level[210][210];
int field[210][210];

int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};

int main() {
	for(int N; cin >> N, N;) {
		memset(level, 0, sizeof level);
		memset(field, -1, sizeof field);
		for(int n = 0; n < N; n++) {
			int t, f;
			cin >> t >> f;
			Dice d(t, f);
			int x = 100;
			int y = 100;
			while(true) {
				if(level[x][y] == 0) break;
				int s = -1;
				int index = -1;
				for(int i = 1; i <= 4; i++) {
					if(d.num[i] <= 3) continue;
					int nx = x + dx[i - 1];
					int ny = y + dy[i - 1];
					if(level[x][y] > level[nx][ny]) {
						if(s < d.num[i]) {
							s = d.num[i];
							index = i;
						}
					}
				}
				if(s == -1) break;
				d.rotate(index);
				int nx = x + dx[index - 1];
				int ny = y + dy[index - 1];
				x = nx;
				y = ny;
			}

			field[x][y] = d.num[0];
			level[x][y]++;
		}

		int cnt[6];
		memset(cnt, 0, sizeof cnt);
		for(int x = 0; x < 210; x++) {
			for(int y = 0; y < 210; y++) {
				if(field[x][y] != 0)
					cnt[field[x][y] - 1]++;
			}
		}
		for(int i = 0; i < 5; i++) {
			cout << cnt[i] << " ";
		}
		cout << cnt[5] << endl;
	}
}