백준: Silver4② - 1063, 1065, 1120
</br>
실버 4 문제들 끝~
강제 갱신하기가 있는 줄 몰랐는데 했더니 점수가 더 올라가서 실버 3이 되었다!
</br>
1063: 킹
https://www.acmicpc.net/problem/1063
체스판에 킹과 돌이 있다. 킹은 한 칸 씩 움직이고, 돌을 밀 수 있지만 밖으로 나가게 된다면 움직이지 않는다.
tuple<int, int> king, stone;
king = make_tuple(s1[0] - 'A', 8 - s1[1] + '0');
stone = make_tuple(s2[0] - 'A', 8 - s2[1] + '0');
for(int i = 0; i < n; i++){
string s;
cin >> s;
int cmd1 = 0, cmd2 = 0;
if( s == "R" ){
cmd1 = 1;
}
if( s == "L" ){
cmd1 = -1;
}
if( s == "T" ){
cmd2 = -1;
}
if( s == "B" ){
cmd2 = 1;
}
if( s == "RT" ){
cmd1 = 1;
cmd2 = -1;
}
if( s == "LT" ){
cmd1 = -1;
cmd2 = -1;
}
if( s == "RB" ){
cmd1 = 1;
cmd2 = 1;
}
if( s == "LB" ){
cmd1 = -1;
cmd2 = 1;
}
if( get<0>(king) + cmd1 != 8 && get<0>(king) + cmd1 != -1
&& get<1>(king) + cmd2 != 8 && get<1>(king) + cmd2 != -1 ){
get<0>(king) = get<0>(king) + cmd1; get<1>(king) = get<1>(king) + cmd2;
if( get<0>(king) == get<0>(stone) && get<1>(king) == get<1>(stone) ){
if( get<0>(stone) + cmd1 != 8 && get<0>(stone) + cmd1 != -1
&& get<1>(stone) + cmd2 != 8 && get<1>(stone) + cmd2 != -1 ){
get<0>(stone) = get<0>(stone) + cmd1; get<1>(stone) = get<1>(stone) + cmd2;
}
else{
get<0>(king) = get<0>(king) - cmd1; get<1>(king) = get<1>(king) - cmd2;
}
}
}
}
s1[0] = get<0>(king) + 'A';
s1[1] = 8 - get<1>(king) + '0';
s2[0] = get<0>(stone) + 'A';
s2[1] = 8 - get<1>(stone) + '0';
cout << s1 << endl;
cout << s2 << endl;
킹 받는 문제다…
많이 뻘짓했다
여기서 거의 대부분 속았을 반례:
- R, L, B, T일 때 그 방향만 체크하면 안 되고 돌과 킹의 위치가 아예 같을 때 돌을 움직여 줘야 함
- 돌이 킹한테 밀렸을 때 돌이 체스판 밖으로 나갈 수도 있음(그럼 움직이면 안 됨)
코드는 그냥 그대로 구현한 거…
상황에 맞게 커맨드 설정하고 위 두 규칙을 신경 쓰면 됨.
</br>
1065: 한수
https://www.acmicpc.net/problem/1065
한수라는 말은 처음 듣는데 아무튼 등차수열을 붙여서 만들어지는 수? ex) 123, 2468
int cnt = 0;
if( n < 100 ) cnt = n;
else{
cnt = 99;
for(int i = 111; i < n+1; i++){
int k = i;
bool isHan = true;
int a, b, c;
a = k % 10;
c = k % 10 - (k / 10) % 10;
a = (k / 10) % 10;
k /= 100;
while( k != 0 ){
b = k % 10;
if(a - b != c ){
isHan = false;
break;
}
a = b;
k /= 10;
}
if( isHan ){
cnt++;
}
}
}
cout << cnt << endl;
백준 예제에서 거의 다 가르쳐 준다.
한 자리 수나 두 자리 수는 무조건 다 한수다. ex) 3, 55, 39
99 다음으로 한수는 111이 있으므로 거기부터 체크한다. 처음에 앞에서부터 떼면서 확인하려 했는데 좀 잘 안 됐는데, 생각해보니까 뒤에서부터 떼도 아무 상관없다. oooba와 같이 a와 b를 구해서 그 둘의 차 c를 구하고, 나머지도 계속 c와 같은 지 확인해 준다.
</br>
1120: 문자열
https://www.acmicpc.net/problem/1120
문자열 A와 B가 있는데(길이 A < B), A의 앞뒤에 알파벳을 추가해서 가장 차이가 적게 하기.
int gap = s2.size() - s1.size();
int minGap = 51;
for(int i = 0; i < gap+1; i++){
int cnt = 0;
for(int j = 0; j < s1.size(); j++){
if( s1[j] != s2[j+i] ) cnt++;
}
minGap = min(minGap, cnt);
}
cout << minGap << endl;
A의 앞뒤만 추가 가능하다는 조건을 안 보고 갑자기 왤케 어려워 졌지?! 했다… local sequence alignment인 줄 알았다
그게 아니고 엄청 간단하다. 문자열 s2와 s1의 길이 차를 구해서, 앞에서부터 그냥 갭을 주면서 차가 제일 적은 걸 구하면 된다.
ex) abc-aaaaa => oabc-aaaaa => ooabc-aaaaa
</br>
킹받는 문제 빼고는 괜찮았다…
점수가 444네ㅋㅋ
다음은 실버 3
</br>
댓글남기기