구현 문제는 어려운 문제는 너무 어렵다.. 모든 문제가 그렇지만 구현과 dp는 어려우면 생각도 못하겠다. 휴 계속 연습해야지....
상하좌우
NxN 크기의 맵에서 LRUD 로 이동하는 문제였는데, 맵의 x와 y를 당연히 좌표와 똑같을 줄 알았지만 달라서 당황했다.
문제에서는
- x와 y가 바뀌어 있고 (오른쪽으로 3칸 아래로 2칸이 (2,3))
- y 좌표는 반대로 되어 있다 (U는 -1, D는 +1)
이 점만 제외하면 쉽게 풀 수 있는 문제였다.
너무 오랜만에 풀어서 좌표 문제를 푸는 방법을 까먹어서 배열에 값을 미리 담아서 사용하지 않고 그냥 풀어서 좀 지저분하지만 어쩔 수 없다. 다음부터는 잊지 말고 풀어야지!
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
int main() {
int N;
int i;
char loc;
int x, y;
int locx=1, locy=1;
scanf("%d", &N);
//getchar();
for (i = 0; i < 6; i++) {
x = 0;
y = 0;
getchar();
scanf("%c", &loc);
if (loc == 'L') {
x = -1;
}
else if (loc == 'R') {
x = 1;
}
else if (loc == 'U') {
y = -1;
}
else if (loc == 'D') {
y = +1;
}
if ((locx + x) <= N && (locx + x) >= 1) {
locx += x;
}
if ((locy + y) <= N && (locy + y) >= 1) {
locy += y;
}
//printf("i: %d loc: %c %d %d\n", i,loc, locx, locy);
}
printf("%d %d", locy, locx);
//왠진 모르겠지만 책에는 x,y 좌표가 반대로 되어있음;
}
/*
5
R R R U D D
*/
시각
0시 0분 0초 ~ N시 59분 59초까지 3이 포함된 모든 경우의 수를 구하는 문제였다.
그냥 다 세면 되는 문제여서 쉬웠다.
처음에는 아무 생각 없이 j==3 || j/10 == 3으로 체크했는데 이러면 3인 경우와 3n인 경우만 체크된다는 것을 깨닫고 j%10 == 3 || j/10 == 3으로 바꿨다. 이 방법으로 1의 자리 수와 10의 자리 수가 3인 경우를 모두 체크할 수 있다.
int main() {
int N;
int i, j, k;
int cnt = 0;
scanf("%d", &N);
for (i = 0; i <= N; i++) {
for (j = 0; j < 60; j++) {
for (k = 0; k < 60; k++) {
if (i == 3)
cnt++;
else if (j / 10 == 3 || j % 10 == 3)
cnt++;
else if (k / 10 == 3 || k % 10 == 3)
cnt++;
}
}
}
printf("%d", cnt);
}
/*
5
*/
왕실의 나이트
체스판에서 나이트를 움직이는 문제로, 주어진 지점에서 이동할 수 있는 경우의 수를 구하는 문제였다.
- 문자로 들어온 좌표를 숫자로 바꿔준다
- 8가지의 방향을 적용해 체스판 범위 안에 들어오는 경우를 세 준다.
나이트가 이동할 수 있는 방향을 locx, locy에 미리 저장해주면 쉽게 풀 수 있다.
int locx[8] = { 2,2,-2,-2,1,-1,1,-1 };
int locy[8] = { 1,-1,1,-1,2,2,-2,-2 };
int main() {
char loc[3];
int nx, ny;
int x, y;
int cnt = 0;
scanf("%s", loc);
x = loc[0] - 'a' + 1; //1부터 시작
y = loc[1] - '1' + 1;
//printf("loc: %s %d %d\n",loc, x, y);
for (int i = 0; i < 8; i++) {
nx = locx[i] + x;
ny = locy[i] + y;
if (nx > 8 || nx < 1 || ny>8 || ny < 1)
continue;
cnt++;
}
printf("%d", cnt);
}
/*
a1
*/
게임 개발
이 문제는 약간 어려웠다.
- 현재 위치에서 왼쪽 (반시계 방향으로 90도)으로 회전
- 방문 전이면 전진, 그렇지 않다면 1로 돌아간다.
- 4방향 모두 가봤거나 바다면 방향을 유지한 채로 후진 후 1로 돌아간다. 이때 뒤가 바다면 끝난다.
북동남서 순서대로 0,1,2,3 의 값을 가지며 4면은 모두 바다다.
내맘대로 문제를 풀어서 위의 방향 관련된 내용은 싸그리 무시하고 풀었더니 이상해져서 다시 문제를 꼼꼼히 읽고 풀었다. ㅎ 문제를 풀 때 절대로! 내맘대로 풀지 말것!!
풀이 과정은 이렇다.
- 왼쪽으로 회전
- 점검 후 (전진 / 1로 돌아가기) 선택
- 4방향 모두 가본 칸이거나 바다일 경우 (후진 / 끝내기) 선택
많은 변수가 전역으로 선언된 이유는.. 내맘대로 문제를 풀 때 전역변수가 필요했었기 때문이다 ㅎ
//북동남서
int dx[4] = { 0,1,0,-1 };
int dy[4] = { 1,0,-1,0 };
int map[51][51];
int visit[51][51] = { 0 };
int cnt = 1; //맨 처음 자리도 세야 함
int N, M;
int turn(int dir) { //북동남서 0123 //문제에서 반시계 방향으로 90도 회전하라고 함
dir -= 1;
if (dir == -1) dir = 3;
return dir;
}
int main() {
int i, j;
int x, y, dir;
int nx, ny;
int turnCnt=0;
scanf("%d %d", &N, &M);
scanf("%d %d %d", &x, &y, &dir);
for (i = 0; i < N; i++) { //맵 초기화
for (j = 0; j < M; j++) {
scanf("%d", &map[i][j]);
}
}
while (1) {
//1. 왼쪽으로 회전
dir = turn(dir);
turnCnt++;
//2. 확인
nx = dx[dir] + x;
ny = dx[dir] + y;
//printf("dir: %d nx,ny: (%d, %d)\n", dir, nx, ny);
if (visit[nx][ny]==0 && map[nx][ny]==0) { //방문하지 않은 곳, 육지
x = nx;
y = ny;
cnt++;
turnCnt = 0;
visit[nx][ny] = 1;
continue;
}
else if(turnCnt == 4) {
//후진
nx = x - dx[dir];
ny = y - dx[dir];
if (map[nx][ny]==1) break; //뒤가 바다면 끝
x = nx;
y = ny;
turnCnt = 0;
}
}
printf("%d", cnt);
}
/*
4 4
1 1 0
1 1 1 1
1 0 0 1
1 1 0 1
1 1 1 1
*/
http://www.yes24.com/product/goods/91433923