www.acmicpc.net/problem/2726

 

2726번: 삼각 N-Queen

각 테스트 케이스에 대해서, 첫 줄에 놓을 수 있는 퀸의 최대 개수를 출력한다. 둘째 줄부터 N개의 줄에는 퀸의 위치를 출력한다. 제일 윗 줄의 번호는 1이고, 그 줄의 가장 왼쪽 칸의 번호는 1이

www.acmicpc.net

1. 풀이방법

 

- 처음에는 백트래킹을 이용한 모든 경우의수를 탐색하는 코드로 짰으나, 시간이 너무 오래걸립니다.

 

- 문제를 보면 N은 최대 1000이나 되기 때문에 다른방법을 찾아야 했고,

 

- 어쩔수 없이 직접 그려보며 규칙을 찾아야 했습니다......후... 근데 규칙 찾기도 상당히 난해합니다.

 

- 테스트케이스를 그리다 보면 어느정도 규칙이 보이는데, 문제는 시작점입니다.

 

- 시작점을 특정하는 것이 매우 어려웠습니다.

 

- 그림을 쭉 테스트케이스처럼 그려보다보면  (여기서 N=3 일 때는 테스트 케이스는 (1,1),(3,2)라고 했지만,

 

- 이것을 (2,1),(3,3)으로 바꿔서 생각하면 테스트케이스에서 어느정도의 일관성을 가진 규칙이 보입니다.

 

- 문제는 시작점을 특정하는 것인데 그려놓고 계속 보다보면 먼저 퀸의 개수가 측정이 가능한데

 

- (1,1,2,3,3,4,5,5,6,7,7,8,9,9,10,11,11,12......) 이런식입니다.

 

- 그래서 퀸의 개수를 먼저 배열에 싹다 구해서 넣어놓습니다.

 

- 그리고 시작점 (X,1)을 찾아야 하는데 이건 제가 찾은 규칙은 (N-퀸의개수+1)이였습니다

 

- 나머지는 부분은 테스트케이스를 직접 그려놓은 것을 바탕으로 구현하시면 됩니다.

 

 

 

 

2. 주의사항

 

- 특이하게도, 백트래킹으로 짠 시간초과가 나는 코드를 이용해서 규칙을 찾는데에 도움을 받아 풀었습니다.

(약 10~11정도까지는 조금 기다리면 나옵니다.) --> 이 코드로 1~11을  써가며 규칙을 찾아 풀었습니다.

 

 

3.나의코드

 

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<queue>
using namespace std;

int t;
int n;
int qarr[1005];

void initqueen() {
	int tmpq = 1;
	int index = 1;
	while (1) {
		if (index > 1000) break;
		qarr[index + 0] = tmpq;
		qarr[index + 1] = tmpq;
		qarr[index + 2] = tmpq + 1;
		tmpq += 2;
		index += 3;
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	initqueen();
	cin >> t;
	while (t--) {
		cin >> n;
		int startx = n - qarr[n] + 1;
		int starty = 1;
		int tmpx = 1;
		cout << qarr[n] << "\n";
		int tsize = qarr[n];
		while (tsize--) {
			cout << startx << " " << starty << "\n";
			if (startx == starty) {
				tmpx++;
				startx += 1;
				starty = tmpx;
				continue;
			}
			startx += 1; starty += 2;
		}
	}
	return 0;
}

'알고리즘 문제풀이 > 구현' 카테고리의 다른 글

백준 19237 [C++]  (0) 2021.03.05
백준 17140 [C++]  (0) 2021.01.24
백준 10993 [C++]  (0) 2021.01.16
백준 20061 [C++]  (0) 2020.12.28
백준 20056 [C++]  (0) 2020.12.23

www.acmicpc.net/problem/10993

 

10993번: 별 찍기 - 18

예제를 보고 규칙을 유추한 뒤에 별을 찍어 보세요.

www.acmicpc.net

1. 풀이방법

 

- 재귀를 이용한 별찍기 문제입니다.

 

- 보통의 별 찍기 문제는 반복문 활용 이고

 

- 조금 난이도가 있는 별찍기 문제는 재귀+반복문 사용 인경우 가 있습니다.

 

- 가로와 세로의 길이 (n에따른)  를 먼저 구하고 재귀로 구현하면 되는 문제였습니다.

 

- 가로는 2^(n+1)-1, 세로는 2^n-1 이였습니다.

 

- 저는 starmap을 문제 조건 n에 따른 최대치 이상을 이차원 배열로 먼저 선언하였습니다.

 

 

 

2. 주의사항

 

- 처음 제출하고 "출력형식이 잘못되었습니다" 가 나와 스크롤을 해보았습니다.

 

-

- 위의 캡처와 같이 바깥쪽 공백은 출력을 하면 안됩니다.

 

- 저는 이미 이차원배열에 ' '까지 모두 들어가도록 짜서 그냥 출력부에서 홀수,짝수 나누어서 조정해주었습니다.

 

 

 

3. 나의코드

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;

int n;
char starmap[2048][2048];

int gety(int n) {
	int fi = 2;
	for (int i = 0; i < n; i++) {
		fi *= 2;
	}
	return (fi - 3);
}
int getx(int n) {
	int fi = 2;
	for (int i = 0; i < n - 1; i++) {
		fi *= 2;
	}
	return (fi - 1);
}

void makestar(int cnt,int startx,int starty) {
	if (cnt == 0) {
		return;
	}
	int cx = getx(cnt);
	int cy = gety(cnt);
	if (cnt % 2 == 0) { //짝수일때 역삼각형
		for (int i = startx; i < startx+cx; i++) {
			for (int j = starty; j <starty+ cy / 2 + 1; j++) {
				if (i == startx) starmap[i][j] = '*';
				else if (j == starty+(i-startx)) starmap[i][j] = '*';
				else starmap[i][j] = ' ';
			}
		}
		for (int i = startx; i < startx+cx; i++) {
			for (int j = starty+cy / 2+1; j < starty+cy; j++) {
				if (i == startx) starmap[i][j] = '*';
				else if (j == starty+cy - 1 - (i-startx)) starmap[i][j] = '*';
				else starmap[i][j] = ' ';
			}
		}
		makestar(cnt - 1, startx +1, starty + cy / 4+1);
	}
	else { //홀수
		for (int i = startx; i <startx+cx; i++) {
			for (int j = starty; j <starty+ cy / 2 + 1; j++) {
				if (i == startx+cx-1) starmap[i][j] = '*';
				else if (j == starty+(cy / 2) - (i-startx)) starmap[i][j] = '*';
				else starmap[i][j] = ' ';
			}
		}
		for (int i = startx; i <startx+cx; i++) {
			for (int j =starty+ cy / 2+1; j <starty+ cy; j++) {
				if (i ==startx+ cx - 1) starmap[i][j] = '*';
				else if (j == starty+(cy / 2) + (i-startx)) starmap[i][j] = '*';
				else starmap[i][j] = ' ';
			}
		}
		makestar(cnt - 1, startx + cx / 2, starty + cy / 4+1);
	}
}
void printstar(int n) {
	int x = getx(n);
	int y = gety(n);
	if (n % 2 == 1) { // 홀수
		for (int i = 0; i < x; i++) {
			for (int j = 0; j <= y/2+i; j++) {
				cout << starmap[i][j];
			}
			cout << "\n";
		}
	}
	else { //짝수
		for (int i = 0; i < x; i++) {
			for (int j = 0; j < y - i; j++) {
				cout << starmap[i][j];
			}
			cout << "\n";
		}
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);


	cin >> n;
	makestar(n, 0, 0);

	printstar(n);

	return 0;
}

 

 

- 별찍기 문제의 장점 !   (풀고나서 출력하면 뿌듯하다)

 

'알고리즘 문제풀이 > 구현' 카테고리의 다른 글

백준 17140 [C++]  (0) 2021.01.24
백준 2726 [C++]  (0) 2021.01.16
백준 20061 [C++]  (0) 2020.12.28
백준 20056 [C++]  (0) 2020.12.23
백준 20055 [C++]  (0) 2020.12.23

www.acmicpc.net/problem/20061

 

20061번: 모노미노도미노 2

모노미노도미노는 아래와 같이 생긴 보드에서 진행되는 게임이다. 보드는 빨간색 보드, 파란색 보드, 초록색 보드가 그림과 같이 붙어있는 형태이다. 게임에서 사용하는 좌표 (x, y)에서 x는 행,

www.acmicpc.net

1. 풀이방법

 

- 문제의 조건을 그대로 구현하는 문제입니다.

 

 

- 문제가 길긴 하지만 테스트케이스 와 문제자체(그림)이 친절하게 나와있어서 과정을 체크하기 편했습니다.

 

 

- 딱히 알고리즘을 사용할 건 없고 조건에 맞춘 구현만 해주시면 됩니다.

 

 

2. 주의사항

 

- 두번정도 틀린 후에 정답을 맞췄는데, 첫번째 오답의 경우 도미노를 밀 때 효율적으로 짠다셈 치고 뒤에서 부터

 

 

- 탐색을 하면서 도형의 자리를 찾았는데 , 오답이 뜬후 디버깅하며 지도 형태를 보니

 

 

- (이러한 경우)

 

 

- 0 0 0 1                    1 0 0 1

  0 1 0 1        (--->)   1 1 0 1  (정답)

 

 

 이렇게 되어야 하는데,

 

 

                                 0 0 1 1

                  (--->)     0 1 1 1 (오답)

 

 

- 이러한 실수를 했어서, 앞쪽부터 탐색하는 것으로 바꾸었습니다. (앞으로도 이런문제에서 주의하자..!!)

 

 

- 두번째 오답은 도형 유형이 3가지 있는데 테트리스를 생각해 보시면 이게 두줄이 한번에 clear 되는 경우가 발생할 수

 

 

- 있습니다. 저 같은 경우 코드 상에서 뒤쪽 부터 탐색 하며 한 행 또는 열 이 클리어 된다면 앞쪽에서 한칸씩 당겨오는

 

 

- 방식으로 구현했는데, 이렇게 구현할 경우 땡겨온 다음 그 행 또는 렬 을 한번 더 체크 해주어야 합니다 ( i++ )

 

 

- 자세한 것은 주석을 확인해주세요

 

 

 

3. 나의코드

 

#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;


int N,t,x,y;
int ground[10][10]; //0~9
int resultscore;
int resultblock;

void fillnemo() {
	if (t == 1) {
		for (int i = 4; i <=9; i++) { //파란색
			if (i == 9) { ground[x][i] = 1; break; }
			if (ground[x][i+1] == 1) { ground[x][i] = 1; break; }
		}
		for (int i = 4; i <= 9; i++) { //초록색
			if (i == 9) { ground[i][y] = 1; break; }
			if (ground[i+1][y] == 1) { ground[i][y] = 1; break; }
		}
	}
	else if (t == 2) {
		int tmpindex=10;
		for (int i = 4; i <= 9; i++) { //파란색
			if (ground[x][i] == 1 ) {
				tmpindex = i;
				break; }
		}
		ground[x][tmpindex - 1] = 1; ground[x][tmpindex - 2] = 1;

		tmpindex = 10;
		for (int i = 4; i <= 9; i++) { //초록색
			if (ground[i][y] == 1||ground[i][y+1]==1) {
				tmpindex = i;
				break;
			}
		}
		ground[tmpindex - 1][y] = 1; ground[tmpindex - 1][y + 1] = 1;
	}
	else {
		int tmpindex = 10;
		for (int i = 4; i <= 9; i++) { //파란색
			if (ground[x][i] == 1 || ground[x + 1][i] == 1) {
				tmpindex = i;
				break;
			}
		}
		ground[x][tmpindex - 1] = 1; ground[x + 1][tmpindex - 1] = 1;
		tmpindex = 10;
		for (int i = 4; i <= 9; i++) { //초록색
			if (ground[i][y] == 1 ) {
				tmpindex = i;
				break;
			}
		}
		ground[tmpindex - 1][y] = 1; ground[tmpindex - 2][y] = 1;
	}
}

void delblock() {
	//파란색
	for (int i = 9; i >= 6; i--) {
		bool checking = false;
		for (int j = 0; j < 4; j++) {
			if (ground[j][i] == 0) { checking = true; break; }
		}
		if (checking == false) { //4블록이 꽉찬경우
			resultscore++;
			for (int k = i; k >= 4; k--) { //이동시키기
				for (int l = 0; l < 4; l++) { ground[l][k] = ground[l][k-1]; }
			}
			i++; // 두줄이 한번에 꽉차는 경우를 위해서 이동시킨후 다시 그 행,렬부터 확인해야됨
		}
	}
	//초록색
	for (int i = 9; i >= 6; i--) {
		bool checking = false;
		for (int j = 0; j < 4; j++) {
			if (ground[i][j] == 0) { checking = true; break; }
		}
		if (checking == false) {
			resultscore++;
			for (int k = i; k >= 4; k--) { //이동시키기
				for (int l = 0; l < 4; l++) { ground[k][l] = ground[k-1][l]; }
			}
			i++; // 두줄이 한번에 꽉차는 경우를 위해서 이동시킨후 다시 그 행,렬부터 확인해야됨
		}
	}
}

void moveblock() { 
	//연한 파란색
	bool checking = false;
	int checkingcount = 0;
	for (int i = 4; i <= 5; i++) {
		for (int j = 0; j < 4; j++) {
			if (ground[j][i] == 1) { checkingcount++; break; }
		}
	}
	if (checkingcount != 0) {
		for (int i = 9; i >= 4; i--) {
			for (int j = 0; j < 4; j++) {
				ground[j][i] = ground[j][i - checkingcount];
			}
		}
	}
	for (int i = 4; i <= 5; i++) {
		for (int j = 0; j < 4; j++) {
			ground[j][i] = 0;
		}
	}
	//연한 초록색
	checking = false;
	checkingcount = 0;
	for (int i = 4; i <= 5; i++) {
		for (int j = 0; j < 4; j++) {
			if (ground[i][j] == 1) { checkingcount++; break; }
		}
	}
	if (checkingcount != 0) {
		for (int i = 9; i >= 4; i--) {
			for (int j = 0; j < 4; j++) {
				ground[i][j] = ground[i-checkingcount][j];
			}
		}
	}
	for (int i = 4; i <= 5; i++) {
		for (int j = 0; j < 4; j++) {
			ground[i][j] = 0;
		}
	}
}
void watchground() {
	cout << endl;
	for (int i = 0; i <= 9; i++) {
		for (int j = 0; j <= 9; j++) {
			cout << ground[i][j];
		}
		cout << endl;
	}
}
void getblock() {
	for (int i = 6; i <= 9; i++) {
		for (int j = 0; j < 4; j++) {
			if (ground[j][i] == true) resultblock++;
		}
	}
	for (int i = 6; i <= 9; i++) {
		for (int j = 0; j < 4; j++) {
			if (ground[i][j] == true) resultblock++;
		}
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> N;
	while (N--) {
		cin >> t >> x >> y;
		fillnemo(); // 블록 초록색 파란색으로 이동시키기
		delblock(); // 4블록이 꽉찬 행,또는 렬 삭제 (점수 획득)
		moveblock(); // 연한초록, 연한파란색에 블록이 있을 경우 이동
	}
	getblock();
	cout << resultscore << "\n";
	cout << resultblock << "\n";

	return 0;
}

 

'알고리즘 문제풀이 > 구현' 카테고리의 다른 글

백준 2726 [C++]  (0) 2021.01.16
백준 10993 [C++]  (0) 2021.01.16
백준 20056 [C++]  (0) 2020.12.23
백준 20055 [C++]  (0) 2020.12.23
백준 13458 [C++]  (0) 2020.12.15

www.acmicpc.net/problem/20056

 

20056번: 마법사 상어와 파이어볼

첫째 줄에 N, M, K가 주어진다. 둘째 줄부터 M개의 줄에 파이어볼의 정보가 한 줄에 하나씩 주어진다. 파이어볼의 정보는 다섯 정수 ri, ci, mi, si, di로 이루어져 있다. 서로 다른 두 파이어볼의 위치

www.acmicpc.net

1. 풀이방법

 

- 구현 문제이고 문제풀이에 필요한 알고리즘은 딱히 없습니다.

 

- 조건을 파악한뒤 이제 파이어볼이 이동할수 있는 지도가 연결되어 있다는 것이 중요한 것 같습니다.

 

- N을 넘어가면 다시 1로 오는 것이죠.

 

- 방향은 친절하게도 지도모양으로 줘서 8방향탐색 dx,dy를 설정해주시면 되고,

 

- 저같은 경우 파이어볼들을 저장하는 벡터 하나와 각 단계에서 ground[51][51]을 벡터로 선언해서,

 

- x,y에 이동한 파이어 볼이 있을경우 push_back으로 각 좌표에 매달아주는 느낌으로 구현하였습니다.

 

- 그렇게 파이어볼이 모두 이동시킨뒤 ground(맵)을 보면서 파이어볼이 없는 좌표는 continue

 

- 한개있는 좌표는 그대로 다시 totalfireball에 push, 두개 이상인 것은 문제 조건에 맞춰 재조정한후

 

- 4개의 파이어볼을 다시 totalfireball에 push 해주었습니다.

 

- 각 단계에서 vector들 clear()를 해주었구요.

 

 

 

 

2. 주의사항

 

- 이게 s(속력)이 최대 1000이 될수도 있습니다.

 

- 그래서 단순히 0보다 작아지면 N을 더해주거나 N보다 커지면 0으로 만들거나 하려면 이 자체도 반복문 처리를 해주어

 

- 합니다 그래서 그냥 아래와 같이 처리하였습니다.

 

- int newx = ((totalfireball[i].x) + dx[totalfireball[i].d] * totalfireball[i].s + 250 * N) % N;
  int newy = ((totalfireball[i].y) + dy[totalfireball[i].d] * totalfireball[i].s + 250 * N) % N;

 

- 250*N을 더해준 이유는 % 모듈러 연산을 할 때 음수가 나오는 것을 방지하기 위함인데

 

- N의 최솟값은 4이고 s의 최대값은 1000이므로 250*N은 1000보다 같거나 크면서 N 모듈러 연산에는 영향을 끼치지 

 

- 않는 수로 설정하였습니다(N의배수 이므로)

 

 

 

 

3. 나의코드

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;

int N, M, K;
int dx[8] = { -1,-1,0,1,1,1,0,-1 };//8방향탐색
int dy[8] = { 0,1,1,1,0,-1,-1,-1 };

struct fireball {
	int x,y,m, s, d;
};
vector<fireball> ground[51][51];
vector<fireball> totalfireball;
void inputs() {
	cin >> N >> M >> K;
	int tx, ty, tm, ts, td;
	for(int i=0;i<M;i++){
		cin >> tx >> ty>>tm>>ts>>td;
		totalfireball.push_back({ tx-1,ty-1,tm,ts,td }); // 난 0~N-1
	}
}
void groundclear() {
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			ground[i][j].clear();
		}
	}
}
void moveball() {
	for (int i = 0; i < totalfireball.size(); i++) {
		int newx = ((totalfireball[i].x) + dx[totalfireball[i].d] * totalfireball[i].s + 250 * N) % N;
		int newy = ((totalfireball[i].y) + dy[totalfireball[i].d] * totalfireball[i].s + 250 * N) % N;
		ground[newx][newy].push_back({ newx,newy,totalfireball[i].m,totalfireball[i].s,totalfireball[i].d });
	}
}
void makenewball() {
	for(int i=0;i<N;i++){
		for (int j = 0; j < N; j++) {
			if (ground[i][j].empty()) continue; //비어있으면.
			else if (ground[i][j].size() == 1) { //파이어볼이 한개
				totalfireball.push_back(ground[i][j][0]);
			}
			else { //두개 이상인 경우
				int newm = 0; int news = 0;
				for (int k = 0; k < ground[i][j].size(); k++) {
					newm += ground[i][j][k].m;
					news += ground[i][j][k].s;
				}
				newm = newm / 5;
				if (newm == 0) continue;
				news = news / ground[i][j].size();


				bool check = false;
				for (int k = 0; k < ground[i][j].size(); k++) { //모두 홀수?
					if (ground[i][j][k].d % 2 == 0) { check = true; break; }
				}
				if (check == false) {
					totalfireball.push_back({ i,j,newm,news,0 });

					totalfireball.push_back({ i,j,newm,news,2 });

					totalfireball.push_back({ i,j,newm,news,4 });

					totalfireball.push_back({ i,j,newm,news,6 });
				continue;
				}

				check = false;
				for (int k = 0; k < ground[i][j].size(); k++) { //모두 짝수?
					if (ground[i][j][k].d % 2 == 1) { check = true; break; }
				}
				if (check == false) {
					totalfireball.push_back({ i,j,newm,news,0 });

					totalfireball.push_back({ i,j,newm,news,2 });

					totalfireball.push_back({ i,j,newm,news,4 });

					totalfireball.push_back({ i,j,newm,news,6 });
					continue;
				}
				// 둘다 아닐경우
				totalfireball.push_back({ i,j,newm,news,1 });

				totalfireball.push_back({ i,j,newm,news,3 });

				totalfireball.push_back({ i,j,newm,news,5 });

				totalfireball.push_back({ i,j,newm,news,7 });
			}
		}
	}
}
long long getm() {
	long long resultm = 0;
	for (int i = 0; i < totalfireball.size(); i++) {
		resultm += totalfireball[i].m;
	}
	return resultm;
}
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	inputs();
	while (K--) {
		groundclear();
		moveball();
		totalfireball.clear();
		makenewball();
	}
	cout << getm() << "\n";


	return 0;
}

'알고리즘 문제풀이 > 구현' 카테고리의 다른 글

백준 10993 [C++]  (0) 2021.01.16
백준 20061 [C++]  (0) 2020.12.28
백준 20055 [C++]  (0) 2020.12.23
백준 13458 [C++]  (0) 2020.12.15
백준 15685 [C++]  (0) 2020.12.08

www.acmicpc.net/problem/20055

 

20055번: 컨베이어 벨트 위의 로봇

길이가 N인 컨베이어 벨트가 있고, 길이가 2N인 벨트가 이 컨베이어 벨트를 위아래로 감싸며 돌고 있다. 벨트는 길이 1 간격으로 2N개의 칸으로 나뉘어져 있으며, 각 칸에는 아래 그림과 같이 1부

www.acmicpc.net

1. 풀이방법

 

- 그냥 조건대로만 구현해 주시면 됩니다.

 

- 컨베이어 벨트는 문제그대로 N의 최대값인 200을 채우고 INDEX를 그대로 쓰려고 201로 선언해주었고

 

- bool 타입의 로봇배열을 그의 절반만 선언해서 벨트의 index와 같이 맞추어 위치를 index로 접근하였습니다.

 

 

2. 주의사항

 

- 굳이 이 문제를 블로그에 남기는 데에는 문제설명자체가 얼핏 잘못이해하기 쉬워서입니다.

 

- 일단 일반적인 우리의 생각으로는 당연히 컨베이어벨트가 한칸움직이면 위의 물건도 따라 움직입니다.

 

- 그리고 이문제에서는 그와 별개로 로봇도 움직일 수 있다. 라는 것이 이 문제입니다.

 

- 결국 일반적인 컨베이어벨트의 이동 + 로봇의 이동이 모두 들어간 문제입니다.

 

- 처음에는 문제의 조건을 읽고 일반적인 컨베이어벨트의 이동에 대한 설명은 없어서 그것을 제외하고 해야하나??

 

- 벨트는 벨트대로 움직이고 나서, 로봇의 이동을 하는 것인가 생각하였지만 그것은 아니였습니다.

 

- 물론 테스트케이스가 여러개라서 그것들을 통해서 위의 의문을 걸러낼 수 있습니다.

 

 

3. 나의코드

#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;

int N, K;
int zerocount;
int p = 0;
int barr[201];
bool robo[101];

void ratate() { //barr[0]는 그냥 tmp용으로 사용
	barr[0] = barr[2 * N];
	for (int i = 2 * N; i >= 2; i--) { //벨트이동
		barr[i] = barr[i - 1];
	}
	for (int i = N - 1; i >= 1; i--) { //로봇이동
		robo[i + 1] = robo[i];
	}
	robo[1] = false;
	barr[1] = barr[0];
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> N >> K;
	for (int i = 1; i <= 2*N; i++) {
		cin >> barr[i];
		if (barr[i] == 0) zerocount++;
	}
	while (1) {
		if (zerocount >= K) break;
		p++;
		ratate();
		if (robo[N] == true) { //내려오는 칸
			robo[N]= false;
		}
		for (int i = N - 1;  i >= 1; i--) { //이동관련
			if (robo[i] == true) {
				if (robo[i + 1] == false && barr[i + 1] >= 1) {
					robo[i] = false; robo[i + 1] = true;
					barr[i + 1]--;
					if (barr[i + 1] == 0) zerocount++;
				}
			}
		}
		if (robo[1] == false && barr[1] >= 1) { //올라가는 칸
			robo[1] = true; barr[1]--;
			if (barr[1] == 0) zerocount++;
		}
	}
	cout << p << "\n";
	return 0;
}

'알고리즘 문제풀이 > 구현' 카테고리의 다른 글

백준 20061 [C++]  (0) 2020.12.28
백준 20056 [C++]  (0) 2020.12.23
백준 13458 [C++]  (0) 2020.12.15
백준 15685 [C++]  (0) 2020.12.08
백준 17144 [C++]  (0) 2020.12.08

www.acmicpc.net/problem/13458

 

13458번: 시험 감독

첫째 줄에 시험장의 개수 N(1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄에는 각 시험장에 있는 응시자의 수 Ai (1 ≤ Ai ≤ 1,000,000)가 주어진다. 셋째 줄에는 B와 C가 주어진다. (1 ≤ B, C ≤ 1,000,000)

www.acmicpc.net

1. 풀이방법

 

- 그냥 구현 문제입니다.

 

- "오직" 이라는 말이 약간 헷갈린다는 정도? 결국 모든 시험장에 총감독관은 1명 있어야 한다는 말입니다.

 

 

 

2. 주의사항

 

- 시험장이 최대 1,000,000 개 시험장당 응시자가 최대 1,000,000 입니다.

 

- 총,부 감독관 모두 1명씩만 감시가능 하다고 생각하면 1,000,000,000,000명이 필요할 수 있습니다.

 

- INT형으로는 부족 long long 자료형을 사용했습니다.

 

 

 

3. 나의코드

 

#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;

int N;
int B, C;
long long resultcount = 0;

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	cin >> N;
	vector<int> examarea(N);
	for (int i = 0; i < N; i++) cin>>examarea[i];
	cin >> B >> C;

		for (int i = 0; i < N; i++) {
			resultcount++;
			examarea[i] -= B;
			if (examarea[i] <= 0) continue; //총 감독관 혼자 감시 가능
			else { 
				if (examarea[i] % C == 0) resultcount += (examarea[i] / C);
				else resultcount += ((examarea[i] / C) + 1); }
		}

	cout << resultcount << "\n";
	return 0;
}

'알고리즘 문제풀이 > 구현' 카테고리의 다른 글

백준 20056 [C++]  (0) 2020.12.23
백준 20055 [C++]  (0) 2020.12.23
백준 15685 [C++]  (0) 2020.12.08
백준 17144 [C++]  (0) 2020.12.08
백준 14499 [C++]  (0) 2020.12.08

www.acmicpc.net/problem/15685

 

15685번: 드래곤 커브

첫째 줄에 드래곤 커브의 개수 N(1 ≤ N ≤ 20)이 주어진다. 둘째 줄부터 N개의 줄에는 드래곤 커브의 정보가 주어진다. 드래곤 커브의 정보는 네 정수 x, y, d, g로 이루어져 있다. x와 y는 드래곤 커

www.acmicpc.net

1. 풀이방법

 

- 처음에 드래곤커브 그림만 보아서는 무슨 규칙인지....그려봐도 무슨규칙인지......반복문으로 표현이 가능한지....

 

- 전혀 풀이방법이 생각이 안나다가.... 문제를 계속 보면 문제에서 직접 방향 0,1,2,3에 대한 정보가 나오고 개인적으로는

 

- 강조하는 느낌....?이 들었습니다.

 

- 드래곤커브를 세대별로 써보면 다음과 같습니다. (방향 0으로 시작할 때)

   - 0세대 :0

   - 1세대 :01

   - 2세대 :0121

   - 3세대 :01212321

   - 4세대 :0121232123032321

 

- 잘보시면 규칙이 있습니다 이전세대에서 다음세대로 넘어갈때 이전세대의 길이만큼 늘어나는데

 

- 이전세대의 역순 INDEX (뒤쪽부터) (curve[reverindex]+1) % 4 가 다음세대에 차례로 추가됩니다.

   (저도 찾지 못해서 힌트를 얻어 알아냈습니다.....)

 

- 이것만 알게되면 방향순서를 차례로 구해서 visit에 방문체크만 해주시면 됩니다.....!

 

 

 

 

2. 주의사항

 

- 좌표계가 제가 평소 익숙하게 (다른 문제에도 자주) 다루는 좌표계랑 반대입니다. 주의 !

 

 

 

 

3. 나의코드

#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<cmath>
using namespace std;

int N;
int x, y, d, g;
bool visit[102][102];
int resultcount;
int dy[4] = { 0,-1,0,1 };// 동북서남(0,1,2,3)
int dx[4] = { 1,0,-1,0 };
int dragon[1024];
void setvisit() {
	for (int i = 0; i < 101; i++) {
		for (int j = 0; j < 101; j++) {
			visit[i][j] = false;
		}
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	setvisit();
	cin >> N;
	for (int i = 0; i < N; i++) {
		cin >> x >> y >> d >> g;
		dragon[0] = d;
		visit[y][x] = true;
		//드래곤커브 방향 구하기
		for (int j = 1; j <= g; j++) { //세대별로
			int reverseindex = pow(2, j - 1) - 1;
			for (int k = pow(2, j - 1); k < pow(2, j); k++) {
				dragon[k] = (dragon[reverseindex] + 1) % 4;
				reverseindex--;
			}
		}
		for (int j = 0; j < pow(2, g); j++) {//방문처리
				x += dx[dragon[j]]; y += dy[dragon[j]];
				visit[y][x] = true;
		}
	}
	for (int i = 0; i < 101; i++) {
		for (int j = 0; j < 101; j++) {
			if (visit[i][j] == true && visit[i + 1][j] == true && visit[i][j + 1] == true && visit[i + 1][j + 1] == true)
				resultcount++;
		}
	}
	cout << resultcount << "\n";
	return 0;
}

'알고리즘 문제풀이 > 구현' 카테고리의 다른 글

백준 20055 [C++]  (0) 2020.12.23
백준 13458 [C++]  (0) 2020.12.15
백준 17144 [C++]  (0) 2020.12.08
백준 14499 [C++]  (0) 2020.12.08
백준 14503 [C++]  (0) 2020.12.08

www.acmicpc.net/problem/17144

 

17144번: 미세먼지 안녕!

미세먼지를 제거하기 위해 구사과는 공기청정기를 설치하려고 한다. 공기청정기의 성능을 테스트하기 위해 구사과는 집을 크기가 R×C인 격자판으로 나타냈고, 1×1 크기의 칸으로 나눴다. 구사

www.acmicpc.net

1. 풀이방법

 

- 온전한 구현문제 인 것 같습니다..

 

- 문제의 조건을 잘 파악하고 문제에서 원하는 대로 구현을 해주면 됩니다.

 

 

 

 

2. 주의사항

 

- 이 문제에서의 먼지가 퍼지는 것과 같이 가정상 한번에 쫙 퍼지는 것은 한좌표의 결과가 다른 좌표의 입력으로 들어가

   는 것을 조심해야 합니다.

 

- 저는 그래서 이전 단계의 좌표계 (roominfo)를 (copyroom)으로 복사해서 연산을 할 때는 copyroom으로 계산하고 결과를 roominfo에 넣었습니다.

 

 

 

3. 나의코드

#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
using namespace std;

int R, C, T;
int roominfo[51][51];
int copyroom[51][51];
int dx[4] = { 0,0,1,-1 }; //동서남북
int dy[4] = { 1,-1,0,0 };
int reverseclockx[4] = { 0,-1,0,1 }; //반시계
int reverseclocky[4] = { 1,0,-1,0 };
int clockx[4] = { 0,1,0,-1 }; //시계
int clocky[4] = { 1,0,-1,0 };
int dust;
vector<pair<int, int>> airfresh;

void inputs() {
	cin >> R >> C >> T;
	for (int i = 0; i < R; i++) {
		for (int j = 0; j < C; j++) {
			cin >> roominfo[i][j];
			if (roominfo[i][j] == -1) {
				pair<int, int> tmpp; tmpp.first = i; tmpp.second = j;
				airfresh.push_back(tmpp);
			}
		}
	}
}

void dustmove() { //먼지이동
	for (int a = 0; a < R; a++) {
		for (int b = 0; b < C; b++) {
			if (roominfo[a][b] == -1) continue;
			int movedust = 0;
			for (int i = 0; i < 4; i++) {
				if (a + dx[i] < 0 || a + dx[i] >= R || b + dy[i] < 0 || b + dy[i] >= C) continue;
				if (roominfo[a + dx[i]][b + dy[i]] == -1) continue;
				roominfo[a + dx[i]][b+dy[i]] += copyroom[a][b] / 5;
				movedust++;
			}
			roominfo[a][b] -= (copyroom[a][b] / 5)*movedust;
		}
	}

}

void airclean() { //순환(공기청정)
	int dir = 0;
	int tmp,tmp2;
	int nextX = airfresh[0].first + reverseclockx[dir]; int nextY = airfresh[0].second + reverseclocky[dir];
	tmp = roominfo[nextX][nextY];
	roominfo[nextX][nextY] = 0;
	while (1) { //위쪽(반시계)
		if (nextX + reverseclockx[dir] == airfresh[0].first &&nextY + reverseclocky[dir] == airfresh[0].second) break; //공기 청정기를 만남
		if (nextX + reverseclockx[dir] == R || nextX + reverseclockx[dir] == -1 || nextY + reverseclocky[dir] == -1 || nextY + reverseclocky[dir] == C) { dir++; continue; }
		nextX += reverseclockx[dir]; nextY += reverseclocky[dir];
		tmp2 = roominfo[nextX][nextY];
		roominfo[nextX][nextY] = tmp;
		tmp = tmp2;
	}
	             //아래쪽(시계)
	dir = 0;
	nextX = airfresh[1].first + clockx[dir];  nextY = airfresh[1].second + clocky[dir];
	tmp = roominfo[nextX][nextY];
	roominfo[nextX][nextY] = 0;
	while (1) {
		if (nextX + clockx[dir] == airfresh[1].first &&nextY + clocky[dir] == airfresh[1].second) break;//공기 청정기를 만남
		if (nextX + clockx[dir] == R || nextX + clockx[dir] == -1 || nextY + clocky[dir] == -1 || nextY + clocky[dir] == C) { dir++; continue; }
		nextX += clockx[dir]; nextY += clocky[dir];
		tmp2 = roominfo[nextX][nextY];
		roominfo[nextX][nextY] = tmp;
		tmp = tmp2;
	}
}
void getdust() {
	for (int i = 0; i < R; i++) {
		for (int j = 0; j < C; j++) {
			if (roominfo[i][j] > 0) dust += roominfo[i][j];
			}
		}
}
void copymap() {
	for (int i = 0; i < R; i++) {
		for (int j = 0; j < C; j++) {
			copyroom[i][j] = roominfo[i][j];
		}
	}
}
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
	inputs();
	for (int i = 0; i < T; i++) {
		copymap();
		dustmove();
		airclean();
	}
	getdust();
	cout << dust << "\n";
	return 0;
}

'알고리즘 문제풀이 > 구현' 카테고리의 다른 글

백준 13458 [C++]  (0) 2020.12.15
백준 15685 [C++]  (0) 2020.12.08
백준 14499 [C++]  (0) 2020.12.08
백준 14503 [C++]  (0) 2020.12.08
백준 14891 [C++]  (0) 2020.12.06

+ Recent posts