PKU 3095 Linear Pachinko

  • 丁寧にシミュレーションをすれば良い
  • 左右に玉が転がる部分の判定ルーチンは使いまわせるように関数化した
bool check(const string& s, int pos, int dir)
{
	for (; 0 <= pos && pos < s.size(); pos += dir) {
		if (s[pos] == '.') {
			return true;
		} else if (s[pos] == '|' || s[pos] == '/' || s[pos] == '\\') {
			return false;
		}
	}

	return true;
}

int main()
{
	string line;
	while (getline(cin, line) && line != "#") {
		double answer = 0;
		for (int start = 0; start < line.size(); ++start) {
			if (line[start] == '.') {
				// A ball dropped into a hole falls through.
				answer += 100.0;
			} else if (line[start] == '_') {
				// A ball dropped onto a floor tile stops immediately.
				answer += 0.0;
			} else if (line[start] == '/') {
				// A ball dropped onto the left side of a mountain rolls to the left across any number of consecutive floor tiles until it falls into a hole, falls off the left end of the machine, or stops by hitting a wall or mountain.
				if (check(line, start - 1, -1)) {
					answer += 100.0;
				}
			} else if (line[start] == '\\') {
				// A ball dropped onto the right side of a mountain behaves similarly.
				if (check(line, start + 1, 1)) {
					answer += 100.0;
				}
			} else if (line[start] == '|') {
				// A ball dropped onto a wall behaves as if it were dropped onto the left or right side of a mountain, with a 50% chance for each.
				if (check(line, start + 1, 1)) {
					answer += 50.0;
				}
				if (check(line, start - 1, -1)) {
					answer += 50.0;
				}
			}
		}

		cout << (int)(answer / line.size()) << endl;
	}
}