[白俊14891号]ギアC++


[14891番ギア]
https://www.acmicpc.net/problem/14891
これは複雑なアルゴリズムがなく,条件に従って実現される問題である.コード長(ヘッダを除く)は約2000バイトであり,正解者の中には700バイトを実現する者もいる.もっと頑張ろう

解答方法


1.


ギアは2次元に並び、1番~4番まで全て入力します.
移動を開始するギア番号と方向をK列の2 D配列で入力します.

2.


まずspin法を実現する.C++のrotateメソッドを使用しました.方向が-1の場合、1次元配列から見ると、左に1つ移動するのと同じです.逆に、1時は1マス右に移動します.

3.


checkEffectメソッドを実装します.隣接する歯車のうち左側に位置する歯車を第1のパラメータに、右側に位置する歯車を第2のパラメータに配置する方法が実現される.左歯車の3番目の歯と右歯車の7番目の歯の値が異なる場合はtrueを返します.

4.


リプルEffectメソッドを実装します.switch文を使用して、1番ギアが回転し始めたときに発生する可能性のある回数に応じてif文を使用してそれぞれの結果を実現します.
ここで注意すべき点は、波及効果が最も遠くまで伸びているところで、遠くのギアから、方向別に回転している(波及効果の連続比較のため、前のギアを繰り上げて回転させることはできない).

5.


score法は最後に点数を計算する方法である.
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <utility>  // pair
#include <tuple>
#include <stack>
#define ll long long
#define INF 1e9
using namespace std;

int ans = 0;
int cogs[5][9];
int k;
int rotation[101][2];

bool checkEffect(int left, int right) {
	return cogs[left][3] != cogs[right][7];
}

int spin(int r, int dir) {
	if(dir == -1) {  // counter-clockwise
		rotate(cogs[r]+1, cogs[r] + 2 , cogs[r] + 9);
	} else if(dir == 1) {  // clockwise
		rotate(cogs[r]+1, cogs[r] + 8, cogs[r] + 9);
	}
	return 0;
}

void rippleEffect(int start, int d) {  // number of cogs

	switch(start) {
		case 1:
			if(checkEffect(1,2)) {  // first arg idx 3 vs. second arg idx 7
				if(checkEffect(2,3)) {
					if(checkEffect(3,4)) {
						spin(4,-d);
					}
					spin(3,d);
				}
				spin(2,-d);
			}
			spin(1,d);
			break;

		case 2:
			if(checkEffect(1,2) || checkEffect(2,3)) {
				if(checkEffect(1,2) && checkEffect(2,3)) {
					if(checkEffect(3,4)) {
						spin(4,d);
					}
					spin(3,-d);
					spin(1,-d);
				} else if(checkEffect(1,2)) {
					spin(1,-d);
				} else if(checkEffect(2,3)) {
					if(checkEffect(3,4)) {
						spin(4,d);
					}
					spin(3,-d);
				}
			}
			spin(2,d);
			break;

		case 3:
			if(checkEffect(2,3) || checkEffect(3,4)) {
				if(checkEffect(2,3) && checkEffect(3,4)) {
					if(checkEffect(1,2)) {
						spin(1,d);
					}
					spin(2,-d);
					spin(4,-d);
				} else if(checkEffect(2,3)) {
					if(checkEffect(1,2)) {
						spin(1,d);
					}
					spin(2,-d);
				} else if(checkEffect(3,4)) {
					spin(4,-d);
				}
			}
			spin(3,d);
			break;
		case 4:
			if(checkEffect(3,4)) {
				if(checkEffect(2,3)) {
					if(checkEffect(1,2)) {
						spin(1,-d);
					}
					spin(2,d);
				}
				spin(3,-d);
			}
			spin(4,d);
			break;
	}

	return;
}

void score() {
	for(int i=1;i<=4;++i) {
		switch(i) {
			case 1:
				if(cogs[i][1] == 1) {
					ans += 1;
				}
				break;
			case 2:
				if(cogs[i][1] == 1) {
					ans += 2;
				}
				break;
			case 3:
				if(cogs[i][1] == 1) {
					ans += 4;
				}
				break;
			case 4:
				if(cogs[i][1] == 1) {
					ans += 8;
				}
				break;
		}
	}

	return;
}

void sol() {
	for(int i=1;i<=k;++i) {
		rippleEffect(rotation[i][0], rotation[i][1]);
	}

	score();
	return;
}

int main(void) {
	// ios_base :: sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);

	for(int i=1;i<=4;++i) {
		for(int j=1;j<=8;++j) {
			scanf("%1d", &cogs[i][j]);
		}
	}
	
	scanf("%d", &k);
	for(int i=1;i<=k;++i) {
		scanf("%d %d", &rotation[i][0], &rotation[i][1]);
	}

	sol();
	
	printf("%d\n", ans);
	
	return 0;
}
注意事項
cout、cin、scanf()、printf()を同時に使用すると、バックグラウンドですぐにエラーが発生し、処理が完了します.筆者は0.1秒で切られて初めて知った.入力を受け取るときは注意しましょう.