[BOJ] 14891. はぐるま
質問する
合計8個のギアの4個が一列に並んでいて、下図のようになっています.また、鋸歯はN極またはS極のいずれかを表す.ギアはナンバー、一番左のギアは1番、右のギアは2番、右のギアは3番、一番右のギアは4番です.
このとき、ギアは常にK回回転します.歯車の回転は一節に準ずる.回転は時計回りと反時計回りがあり、下図のように回転します.
ギアを回転させるには、回転するギアと回転の方向を決めなければなりません.ギアが回転すると、互いに接触する極に応じて隣のギアを回転させてもよいし、回転させなくてもよい.ギアAを回転させる際に、その隣のギアBと互いに接触するギアの極性が異なると、BはAの回転方向とは逆になる.例えば、以下の状況を見てみましょう.
2つのギアの噛み合い部分は緑色の破線で縛られた部分です.ここで、ギア3ポチを反時計回りに回すと、ギア4ポチが時計回りに回ります.2番ギアの噛み合い部分がS極なので回転せず、1番ギアは2番が回転していないので回転しません.したがって、下図のような形状が作成されます.
上記の状態では、1番ギアを時計回りに回転させ、2番ギアを反時計回りに回転させ、2番ギアを回転させるので、3番も同時に時計回りに回転させます.4番は3番回転ですが、接触が極めて同じなので回転しません.このため、次の状態になります.
ギアの初期状態とギアの回転方法を指定する場合は、最終ギアの状態を求めるプログラムを作成します.
入力
1行目は1番ギアの状態、2行目は2番ギアの状態、3行目は3番ギアの状態、4行目は4番ギアの状態を示します.状態は8個の整数からなり,12時方向から時計回りに与えられる.Nは極めて0,Sは極めて1である.
5行目は回転数K(1≦K≦100)を与える.次のK行は順番に回転の方法を与えます.各方法は2つの整数からなり、第1の整数は回転歯車の番号であり、第2の整数は方向である.方向が1の場合は時計回り、-1の場合は反時計回りです.
しゅつりょく
合計K回回転した後、4個のギアの積分の和を出力します.点数は次のように計算されます.
1番ギアの12点方向はN極0点、S極1点
2番ギアの12時方向がN極0、S極2の場合.
3番ギアの12時方向がN極なら0点、S極なら4点です.
4番ギアの12時方向がN極なら0時、S極なら8時です.
入力例1
10101111
01111101
11001110
00000010
2
3 -1
1 1
サンプル出力1
7
入力例2
11111111
11111111
11111111
11111111
3
1 1
2 1
3 1
サンプル出力2
15
入力例3
10001011
10000011
01011011
00111101
5
1 1
2 1
3 1
4 1
1 -1
サンプル出力3
6
入力例4
10010011
01010011
11100011
01010101
8
1 1
2 1
3 1
4 1
1 -1
2 -1
3 -1
4 -1
サンプル出力4
5
に答える
質問のタイプ:シミュレーション
1.ギア4個の状態と回転回数(K)を入力します.
2.回転数で回転するギア番号と回転方向(1:クロック、-1:半クロック)を入力し、現在のギア回転時に回転する隣接ギアの回転方向をアレイに格納するか否か(1 or-1)によって判断する.(回転して回転するか否かは判断できず、配列で判断して回転する.)
3.1~4番のギアが配列に方向を格納している場合は、回転します.
4.最後に、12:00方向の鋸歯(インデックス1に格納されている値)が0であって(N極)ではない場合(S極)の場合2^インデックスを計算するために、1<<インデックスでスコアを計算した.
コード#コード#
合計8個のギアの4個が一列に並んでいて、下図のようになっています.また、鋸歯はN極またはS極のいずれかを表す.ギアはナンバー、一番左のギアは1番、右のギアは2番、右のギアは3番、一番右のギアは4番です.
このとき、ギアは常にK回回転します.歯車の回転は一節に準ずる.回転は時計回りと反時計回りがあり、下図のように回転します.
ギアを回転させるには、回転するギアと回転の方向を決めなければなりません.ギアが回転すると、互いに接触する極に応じて隣のギアを回転させてもよいし、回転させなくてもよい.ギアAを回転させる際に、その隣のギアBと互いに接触するギアの極性が異なると、BはAの回転方向とは逆になる.例えば、以下の状況を見てみましょう.
2つのギアの噛み合い部分は緑色の破線で縛られた部分です.ここで、ギア3ポチを反時計回りに回すと、ギア4ポチが時計回りに回ります.2番ギアの噛み合い部分がS極なので回転せず、1番ギアは2番が回転していないので回転しません.したがって、下図のような形状が作成されます.
上記の状態では、1番ギアを時計回りに回転させ、2番ギアを反時計回りに回転させ、2番ギアを回転させるので、3番も同時に時計回りに回転させます.4番は3番回転ですが、接触が極めて同じなので回転しません.このため、次の状態になります.
ギアの初期状態とギアの回転方法を指定する場合は、最終ギアの状態を求めるプログラムを作成します.
入力
1行目は1番ギアの状態、2行目は2番ギアの状態、3行目は3番ギアの状態、4行目は4番ギアの状態を示します.状態は8個の整数からなり,12時方向から時計回りに与えられる.Nは極めて0,Sは極めて1である.
5行目は回転数K(1≦K≦100)を与える.次のK行は順番に回転の方法を与えます.各方法は2つの整数からなり、第1の整数は回転歯車の番号であり、第2の整数は方向である.方向が1の場合は時計回り、-1の場合は反時計回りです.
しゅつりょく
合計K回回転した後、4個のギアの積分の和を出力します.点数は次のように計算されます.
1番ギアの12点方向はN極0点、S極1点
2番ギアの12時方向がN極0、S極2の場合.
3番ギアの12時方向がN極なら0点、S極なら4点です.
4番ギアの12時方向がN極なら0時、S極なら8時です.
入力例1
10101111
01111101
11001110
00000010
2
3 -1
1 1
サンプル出力1
7
入力例2
11111111
11111111
11111111
11111111
3
1 1
2 1
3 1
サンプル出力2
15
入力例3
10001011
10000011
01011011
00111101
5
1 1
2 1
3 1
4 1
1 -1
サンプル出力3
6
入力例4
10010011
01010011
11100011
01010101
8
1 1
2 1
3 1
4 1
1 -1
2 -1
3 -1
4 -1
サンプル出力4
5
に答える
質問のタイプ:シミュレーション
1.ギア4個の状態と回転回数(K)を入力します.
2.回転数で回転するギア番号と回転方向(1:クロック、-1:半クロック)を入力し、現在のギア回転時に回転する隣接ギアの回転方向をアレイに格納するか否か(1 or-1)によって判断する.(回転して回転するか否かは判断できず、配列で判断して回転する.)
3.1~4番のギアが配列に方向を格納している場合は、回転します.
4.最後に、12:00方向の鋸歯(インデックス1に格納されている値)が0であって(N極)ではない場合(S極)の場合2^インデックスを計算するために、1<<インデックスでスコアを計算した.
コード#コード#
import java.io.*;
import java.util.*;
public class Main_bj_14891_톱니바퀴 {
static char[][] wheels;
static int[] isrotate;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
wheels = new char[4][10]; // 0~3 번 바퀴들을 담는 배열
for (int i = 0; i < 4; i++) {
String s = br.readLine();
for(int j=1; j<=8; j++) {
wheels[i][j] = s.charAt(j-1); // 1번~8번 톱니바퀴까지 들어감 (0과 9번은 회전할 때 사용)
}
}
int K = Integer.parseInt(br.readLine()); // 회전하는 수
StringTokenizer st;
for (int i = 0; i < K; i++) {
isrotate = new int[4]; // 회전할 방향을 담는 배열
st = new StringTokenizer(br.readLine(), " ");
int num = Integer.parseInt(st.nextToken()) - 1; // 회전할 바퀴 번호
int dir = Integer.parseInt(st.nextToken()); // 회전할 방향
isrotate[num] = dir;
checkRotate(num, dir); // 옆에 있는 바퀴들이 회전할 지 게산하는 함수
for(int j=0; j<4; j++) { // 0~3번 바퀴들이 0이 아니라면 회전한다.
if(isrotate[j]!=0)
rotate(j, isrotate[j]);
}
}
int ans = 0;
// 점수 계산
// 12시 방향의 바퀴 값이([1]) S극(1)이면 더한다.
// 0번 : +1 = 2^0
// 1번 : +2 = 2^1
// 2번 : +4 = 2^2
// 3번 : +8번 = 2^3
for(int i=0; i<4; i++) {
if(wheels[i][1]=='1') {
ans += 1<<i;
}
}
System.out.println(ans);
br.close();
}
static void checkRotate(int num, int dir) {
// 왼쪽 바퀴 회전 여부
if(num-1>=0 && isrotate[num-1]==0 && wheels[num][7] != wheels[num-1][3]) {
isrotate[num-1] = -dir;
checkRotate(num-1, -dir);
}
// 오른쪽 바퀴 회전 여부
if(num+1<=3 && isrotate[num+1]==0 && wheels[num][3] != wheels[num+1][7]) {
isrotate[num+1] = -dir;
checkRotate(num+1, -dir);
}
}
static void rotate(int num, int dir) {
if (dir == 1) { // 오른쪽으로 회전
for (int i = 9; i > 1; i--) {
wheels[num][i] = wheels[num][i - 1];
}
wheels[num][1] = wheels[num][9];
} else { // 왼쪽으로 회전
for (int i = 0; i < 8; i++) {
wheels[num][i] = wheels[num][i+1];
}
wheels[num][8] = wheels[num][0];
}
}
}
Reference
この問題について([BOJ] 14891. はぐるま), 我々は、より多くの情報をここで見つけました https://velog.io/@erin_lee/BOJ-14891.-톱니바퀴テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol