www.acmicpc.net/problem/14499

 

14499번: 주사위 굴리기

첫째 줄에 지도의 세로 크기 N, 가로 크기 M (1 ≤ N, M ≤ 20), 주사위를 놓은 곳의 좌표 x y(0 ≤ x ≤ N-1, 0 ≤ y ≤ M-1), 그리고 명령의 개수 K (1 ≤ K ≤ 1,000)가 주어진다. 둘째 줄부터 N개의 줄에 지도

www.acmicpc.net

1. 풀이방법

 

- 문제의 조건을 잘 파악합니다 (처음 읽으면 이게 뭔말인가......싶습니다.)

 

- 주사위에서 잠깐 멈칫했지만 주사위 전개도를 가지고 동/서/북/남 으로 돌렸을 때의 전개도도 그려보고

 

- 이동방향에 따라 값을 수정해주면 됩니다

 

- 저같은 경우 윗면은 항상 dice[1], 아랫면은 항상 dice[6]

 

 

 

 

2. 주의사항

 

- 문제를 읽고 이해하기

 

 

 

3. 나의코드

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


int N, M, K;
int x, y;
int jido[21][21];
int dice[7]; //주사위 (1~6면) //윗면이 무조건 dice[1] ,아랫면이 dice[6]
int dx[5] = { 0,0,0,-1,1 };
int dy[5] = { 0,1,-1,0,0 };

void movedice(int c) {
	if(c==1){ //동
		int tmpdice[7];
		tmpdice[6] = dice[3]; tmpdice[3] = dice[1];
		tmpdice[4] = dice[6]; tmpdice[1] = dice[4];
		tmpdice[5] = dice[5]; tmpdice[2] = dice[2];
		for (int i = 1; i < 7; i++) dice[i] = tmpdice[i];
	}
	if(c==2){
		int tmpdice[7];
		tmpdice[6] = dice[4]; tmpdice[3] = dice[6];
		tmpdice[4] = dice[1]; tmpdice[1] = dice[3];
		tmpdice[5] = dice[5]; tmpdice[2] = dice[2];
		for (int i = 1; i < 7; i++) dice[i] = tmpdice[i];
	}
	if (c == 3){
		int tmpdice[7];
		tmpdice[6] = dice[2]; tmpdice[2] = dice[1];
		tmpdice[5] = dice[6]; tmpdice[1] = dice[5];
		tmpdice[3] = dice[3]; tmpdice[4] = dice[4];
		for (int i = 1; i < 7; i++) dice[i] = tmpdice[i];
	}
	if (c == 4) {
		int tmpdice[7];
		tmpdice[6] = dice[5]; tmpdice[2] = dice[6];
		tmpdice[5] = dice[1]; tmpdice[1] = dice[2];
		tmpdice[3] = dice[3]; tmpdice[4] = dice[4];
		for (int i = 1; i < 7; i++) dice[i] = tmpdice[i];
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> N >> M >>x>>y>>K;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			cin >> jido[i][j];
		}
	}
	int command;
	for (int i = 0; i < K; i++) {
		cin >> command;
		if (x + dx[command] < 0 || x + dx[command] >= N || y + dy[command] < 0 || y + dy[command] >= M) continue;
		movedice(command);
		if (jido[x + dx[command]][y + dy[command]] == 0) {
			jido[x + dx[command]][y + dy[command]] = dice[6];
		}
		else {
			dice[6] = jido[x + dx[command]][y + dy[command]];
			jido[x + dx[command]][y + dy[command]] = 0;
		}
		x += dx[command]; y += dy[command];
		cout << dice[1] << "\n";
	}
	return 0;
}

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

백준 15685 [C++]  (0) 2020.12.08
백준 17144 [C++]  (0) 2020.12.08
백준 14503 [C++]  (0) 2020.12.08
백준 14891 [C++]  (0) 2020.12.06
백준 2840 [C++]  (0) 2020.12.06

www.acmicpc.net/problem/14503

 

14503번: 로봇 청소기

로봇 청소기가 주어졌을 때, 청소하는 영역의 개수를 구하는 프로그램을 작성하시오. 로봇 청소기가 있는 장소는 N×M 크기의 직사각형으로 나타낼 수 있으며, 1×1크기의 정사각형 칸으로 나누어

www.acmicpc.net

1. 풀이방법.

- 문제의 조건대로 차례로 구현을 해주면 되며,

- 문제에서 첫행,첫열,끝행,끝열은 모두 벽이다 라는 조건도 맞추어 주었으므로 경계의 범위도 신경쓰지 않아도 되서

- 매우 편한 문제였습니다.

- 저 같은 경우 3,4 번의 종료조건을 먼저 체크해주고 그것의 결과에따라 변동을 주는 쪽으로 코드를 짰습니다.

 

 

 

2. 주의사항

- 딱히 없습니다. (저는 청소할 구역은 0, 벽은 1, 청소한 구역은 2 로 설정하였습니다.)

 

 

 

3.나의코드

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

int dx[4] = { -1,0,1,0 }; //북동남서
int dy[4] = { 0,1,0,-1 }; //0,1,2,3
int N, M;
int rx, ry, rd;
int robomap[51][51]; //빈칸은 0, 벽은 1
int cleancount;

void inputs() {
	cin >> N >> M;
	cin >> rx >> ry >> rd;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			cin >> robomap[i][j];
		}
	}
}

void cleanroom() {
	while (1) {
		if (robomap[rx][ry] == 0) {
			robomap[rx][ry] = 2; //청소
			cleancount++;
		}
		bool lastcheck = false;
		for (int i = 0; i < 4; i++) {//종료조건 검사
			if (robomap[rx + dx[i]][ry + dy[i]] == 0) { lastcheck = true; break; }
		}
		if (lastcheck == false) {
			if (robomap[rx + dx[(rd + 2) % 4]][ry + dy[(rd + 2) % 4]] == 1) { 
				cout << cleancount << "\n"; break;
			}
			else {
				rx += dx[(rd + 2) % 4]; ry += dy[(rd + 2) % 4];
			}
		}
		else if (lastcheck == true) {
			while (1) {
				if (robomap[rx + dx[(rd + 3) % 4]][ry + dy[(rd + 3) % 4]] == 0) {
					rd = (rd + 3) % 4;
					rx += dx[rd]; ry += dy[rd];
					break;
				}
				else {
					rd = (rd + 3) % 4;
				}
			}
		}
	}
}

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

	return 0;
}

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

백준 17144 [C++]  (0) 2020.12.08
백준 14499 [C++]  (0) 2020.12.08
백준 14891 [C++]  (0) 2020.12.06
백준 2840 [C++]  (0) 2020.12.06
백준 2033 C++  (0) 2020.11.25

www.acmicpc.net/problem/14891

 

14891번: 톱니바퀴

첫째 줄에 1번 톱니바퀴의 상태, 둘째 줄에 2번 톱니바퀴의 상태, 셋째 줄에 3번 톱니바퀴의 상태, 넷째 줄에 4번 톱니바퀴의 상태가 주어진다. 상태는 8개의 정수로 이루어져 있고, 12시방향부터

www.acmicpc.net

1. 풀이방법

- 구현문제입니다.. 그냥 문제에서 주는 조건에 맞춰 구현만하면 되는 듯 합니다.

 

- 톱니바퀴 개수도 정해져있고... 쉬운편인 것 같습니다.

 

- 저는 0,1,2,3 톱니바퀴에 대한 회전유무를 판단하는 벡터를 선언해서 돌아갈 지 말지를 체크해준 뒤

   돌렸습니다....!

 

 

 

2. 주의사항

- 처음에 연쇄적인 회전(?) 일까 라고 생각했는데 그건 아니고 4개가 한번에 빡 돌아가는 그런 것...

 

 

 

3. 나의코드

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

char topni[4][8];
int K;
int resultscore;

void inputs() {
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 8; j++) {
			cin >> topni[i][j];
		}
	}
}


void rotate(int index, int dir) { //0,1,2,3
	vector<pair<bool,int>> turn(4); //first= 회전할지 말지, second=방향

	for (int i = 0; i < 4; i++) { //초기화
		turn[i].first = false; turn[i].second = 0;
	}
	turn[index].first = true; turn[index].second = dir;
	//왼쪽확인
	char current=topni[index][6];
	int direction = dir;

	for (int i = index - 1; i >= 0; i--) {
		if (current != topni[i][2]) {
			turn[i].first = true; turn[i].second = (-1)*direction; //반대방향
			current = topni[i][6]; direction *= (-1);
		}
		else break; //이게 회전을 안한다면 그 옆은 볼필요 x
	}
	//오른쪽확인
	direction = dir;
	current = topni[index][2];
	for (int i = index + 1; i < 4; i++) {
		if(current!=topni[i][6]) {
			turn[i].first = true; turn[i].second = (-1)*direction;
			current = topni[i][2]; direction *= (-1);
		}
		else break; //이게 회전을 안한다면 그 옆은 볼필요 x
	}
	
	//회전
	for (int i = 0; i < 4; i++) {
		if (turn[i].first == true) { //회전한다면
			if (turn[i].second == 1) { //시계방향
		  		char tmp=topni[i][7];
				for (int j = 6; j >= 0; j--) topni[i][j + 1] = topni[i][j];
				topni[i][0] = tmp;
			}
			else { //반시계방향
				char tmp = topni[i][0];
				for (int j = 1; j <= 7; j++) topni[i][j - 1] = topni[i][j];
				topni[i][7] = tmp;
			}
		}
	}
}
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cin.tie(0);
	inputs();
	cin >> K;
	int index, dir;
	for (int i = 0; i < K; i++) {
		cin >> index >> dir;
		rotate(index-1, dir);
	}
	if (topni[0][0] == '1') resultscore += 1;

	if (topni[1][0] == '1') resultscore += 2;

	if (topni[2][0] == '1') resultscore += 4;

	if (topni[3][0] == '1') resultscore += 8;

	cout << resultscore << "\n";

	return 0;
}

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

백준 14499 [C++]  (0) 2020.12.08
백준 14503 [C++]  (0) 2020.12.08
백준 2840 [C++]  (0) 2020.12.06
백준 2033 C++  (0) 2020.11.25
백준 14890 [C++]  (0) 2020.10.21

www.acmicpc.net/problem/2840

 

2840번: 행운의 바퀴

첫째 줄에 마지막 회전에서 화살표가 가리키는 문자부터 시계방향으로 바퀴에 적어놓은 알파벳을 출력한다. 이때, 어떤 글자인지 결정하지 못하는 칸은 '?'를 출력한다. 만약, 상덕이가 적어놓

www.acmicpc.net

1. 풀이방법 

- 구현자체는 어렵지 않습니다..

 

- 배열은 ?로 초기화 해주고

 

- 조건에 따라 INDEX를 취향 껏 조절하시면 됩니다. (방향에 맞춰)

 

 

 

2. 주의사항

- 많이 틀린 이유......예외사항이 중요합니다....

 

- (1) 같은 문자가 바퀴에 중복으로 붙여져서는 안된다.

 

- (2) 한 자리에 여러개의 문자가 붙여질 수는 없다.

 

- 이 떄는 !를 출력해야합니다.

 

- !!!!! 단, 입력은 돌리면서 상황을 보여주는 것이기 때문에 돌렸을 때 상황이 같은 자리를 가리킬 수도 있기 때문에

 

- 입력으로 같은 문자가 두번이 들어와도 그것이 같은자리를 가리키고 있는 경우에는 허용이 됩니다...!!

 

- 이를 조건문에 추가로 걸어주어야 합니다 !

 

- 너무 쉽다생각했다가 예외처리에서 애좀 먹은 문제입니다...ㅠ

 

 

 

3. 나의코드

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

int N, K;
void setpan(vector<char> &pan) {
	for (int i = 0; i < N; i++) {
		pan[i] = '?';
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> N >> K;
	vector<char> pan(N);
	setpan(pan);
	int index;
	for (int i = 0; i < K; i++) {
		int count; char tmpc;
		cin >> count >> tmpc;
		if (i == 0) { pan[0] = tmpc; index = 0; continue; }
		index = (count + index) % N;
		//돌렸을 때 같은문자(같은 자리)는 나올 수 있다. 그것마저 아니면 틀린 원판
		if (pan[index] != '?'&& pan[index] != tmpc) { cout << "!"; return 0; }
		else {
			pan[index] = tmpc;
		}
	}
	//중복체크
	for (int i = 0; i < N; i++) {
		for (int j = i + 1; j < N; j++) {
			if(pan[i]!='?' &&pan[i]==pan[j]) { cout << "!"; return 0; }
		}
	}
	for (int i = 0; i < N; i++) {
		cout << pan[index];
		index--;
		if (index == -1) index = N - 1;
	}
	return 0;
}

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

백준 14503 [C++]  (0) 2020.12.08
백준 14891 [C++]  (0) 2020.12.06
백준 2033 C++  (0) 2020.11.25
백준 14890 [C++]  (0) 2020.10.21
백준 17406 [C++]  (0) 2020.10.18

 

www.acmicpc.net/problem/2033

 

2033번: 반올림

정수 N이 주어져 있을 때 이 수가 10보다 크면 일의 자리에서 반올림을 하고, 이 결과가 100보다 크면 다시 10의 자리에서 반올림을 하고, 또 이 수가 1000보다 크면 100의 자리에서 반올림을 하고.. (

www.acmicpc.net

1. 풀이 방법

- 문제를 잘 읽고 뒷자리 수부터 차례대로 반올림을 실행하시면 됩니다.

 

2. 주의 사항

- 문제를 잘읽읍시다. (전.. 제대로 안읽어서 제일 앞자리 다음 수 (두번쨰자리수) 에서만 반올림 하게 짰다가 그게 아니더라구요);; 귀찮;; 

 

3. 나의 소스

#include<iostream>
using namespace std;

int N;
int initnum=10;
int tmp;

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin>>N;
    while(N/initnum!=0){
        if(N%initnum>=5*(initnum/10)){
                N+=initnum*1;
                tmp=(N%initnum)/(initnum/10);
                N-=(tmp*(initnum/10));
        }
        else {
            tmp=(N%initnum)/(initnum/10);
            N-=(tmp*(initnum/10));
            }
        initnum*=10;
    }
    cout<<N<<"\n";
    return 0;
}

 

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

백준 14891 [C++]  (0) 2020.12.06
백준 2840 [C++]  (0) 2020.12.06
백준 14890 [C++]  (0) 2020.10.21
백준 17406 [C++]  (0) 2020.10.18
백준 15686 [C++]  (0) 2020.10.17

www.acmicpc.net/problem/14890

 

14890번: 경사로

첫째 줄에 N (2 ≤ N ≤ 100)과 L (1 ≤ L ≤ N)이 주어진다. 둘째 줄부터 N개의 줄에 지도가 주어진다. 각 칸의 높이는 10보다 작거나 같은 자연수이다.

www.acmicpc.net

1. 풀이방법.

 

- 말 그대로 그냥 문제 조건을 구현해야 하는데...

 

 

- 처음엔 왼쪽으로 쭉한번보고 오른쪽으로 쭉한번보고 위아래도 마찬가지로 하면된다 생각했었는데

 

 

- 223322 [L=2] 같은 경우가 안되는 것을 보고 접근 방식을 바꿨습니다.

 

 

-높이가 1차이 나는 친구를 만날경우 나보다 큰 친구면 나부터 뒤쪽을 보고

 

 

- 나보다 작은 친구면 나의 앞쪽부터 L만큼을 살펴 보았습니다.

 

 

 

 

 

 

2. 주의사항

 

- 나보다 큰 친구, 작은친구 의 분류로 나눠서 확인할 때, 저는 현재 위치를 INIT 앞쪽 친구를 loadmap[i][j]로 두었기 때문

 

 

- 에 비교문에서 값에 신경을 써야했습니다.

 

 

- 문제에 다양한 예시입력이 있어서 다행이었습니다.....아니였으면 꽤 오래 답을 찾아야 했을 것 같습니다.

 

 

- 후....문제에 대한 아이디어가 생각나면 그 아이디어로 해결이 될 것만 같은 [즉, 예외되는 사항이 발생하는 경우 를 잘

 

 

-떠올리지 못하는 것 같습니다]

 

 

- 코드를 작성하기 전에 한번 더 생각해보고 천천히 접근하자.....!

 

 

 

 

3. 나의코드

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

int N;
int loadmap[101][101];
int L;
int result = 0;
int init;
bool check;
bool checkrow[101];

void inputs() {
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			cin >> loadmap[i][j];
		}
	}
}
int gap(int a, int b) {
	if (a > b) return a - b;
	else { return b - a; }
}
void initcheck() {
	for (int i = 0; i < 101; i++) {
		checkrow[i] = 0;
	}
}
void lookr() {
	for (int i = 0; i < N; i++) {
		initcheck();
		init = loadmap[i][0];
		check = true;
		for (int j = 1; j < N; j++) {
			if (init == loadmap[i][j]) { init = loadmap[i][j]; continue; }
			if (gap(init, loadmap[i][j]) == 1) { //높이1차이
				if (init < loadmap[i][j]) { //벽을 만남(나보다 큰)
					if (j - L < 0) { check = false; break; }
					else {
						for (int k = 1; k <= L; k++) {
							if(checkrow[j-k]==true || loadmap[i][j - k] != init)
							 { check = false; break; }
						}
						for (int k = 1; k <= L; k++) {
							checkrow[j - k] = true;
						}
						if (check == false) break;
					}
				}
				else { //나보다 작은 친구를 만남
					if(j+L>N) { check = false; break; }
					else{
						for (int k = 0; k < L; k++) {
							if (checkrow[j+k]==true||loadmap[i][j + k] != init-1)
							{ check = false; break; }
						}
						for (int k = 0; k < L; k++) {
							checkrow[j + k] = true;
						}
						if (check == false) break;
						j += L-1; //앞에다가 경사로를 놓았을 경우 점프가 필요
					}
				}
			}
			else {check = false; break;} //높이1차이 이상
		init = loadmap[i][j];
		}
		if (check == true) { result++;  }
	}
}
void looku() {
	for (int i = 0; i < N; i++) {
		initcheck();
		init = loadmap[0][i];
		check = true;
		for (int j = 1; j < N; j++) {
			if (init == loadmap[j][i]) { init = loadmap[j][i]; continue; }
			if (gap(init, loadmap[j][i]) == 1) { //높이1차이
				if (init < loadmap[j][i]) { //벽을 만남(나보다 큰)
					if (j - L < 0) { check = false; break; }
					else {
						for (int k = 1; k <= L; k++) {
							if (checkrow[j - k] == true || loadmap[j - k][i] != init)
							{
								check = false; break;
							}
						}
						for (int k = 1; k <= L; k++) {
							checkrow[j - k] = true;
						}
						if (check == false) break;
					}
				}
				else { //나보다 작은 친구를 만남
					if (j + L > N) { check = false; break; }
					else {
						for (int k = 0; k < L; k++) {
							if (checkrow[j + k] == true || loadmap[j + k][i] != init - 1)
							{
								check = false; break;
							}
						}
						for (int k = 0; k < L; k++) {
							checkrow[j + k] = true;
						}
						if (check == false) break;
						j += L-1; //앞에다가 경사로를 놓았을 경우 점프가 필요
					}
				}
			}
			else { check = false; break; } //높이1차이 이상
			init = loadmap[j][i];
		}
		if (check == true) { result++;  }
	}
}

void checkingload() {
	lookr();
	looku();
	cout << result;
}

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

	cin >> N >> L;
	inputs();
	checkingload();
	return 0;
}

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

백준 2840 [C++]  (0) 2020.12.06
백준 2033 C++  (0) 2020.11.25
백준 17406 [C++]  (0) 2020.10.18
백준 15686 [C++]  (0) 2020.10.17
백준 3190 [C++]  (0) 2020.10.17

www.acmicpc.net/problem/17406

 

17406번: 배열 돌리기 4

크기가 N×M 크기인 배열 A가 있을때, 배열 A의 값은 각 행에 있는 모든 수의 합 중 최솟값을 의미한다. 배열 A가 아래와 같은 경우 1행의 합은 6, 2행의 합은 4, 3행의 합은 15이다. 따라서, 배열 A의

www.acmicpc.net

 

 

1. 풀이 방법

 

- 경우의 수는 명령의 순서에 따라 결과가 달라지므로 순열로 구했습니다.

 

 

- 회전을 구현해야 하는데, 바깥쪽 부터 한 겹씩 회전을 시키는 순으로 했고

=

  맨 안쪽에 남은 하나는 오른쪽으로 가려고 하는데 이미 방문한 곳이면 break 하게끔 하였습니다.

 

 

-코드가 많이 길어졌네요...ㅠ

 

 

 

 

2.주의할 점.

 

- 코드가 길어지다보니 처음 짠 부분에서 이곳 저곳에서 문제가 발생...

   디버깅을 한참했습니다...

 

 

-디버깅을 아예 안하기는 쉽지 않겠지만 처음 짤 때 그래도 좀 세심하게 해야겠네요...

 

 

-그리고 (r-s,r+s) 입력이 이런식 이기때문에 행과 열의 수는 모두 홀수 입니다.

(처음에 짝수 개도 되는 경우의 수도 생각하고 짰었는데...풀다보니 발견...)

 

 

- 조건에 따른 문제를 정확하게 파악해야겠습니다...

 

 

 

 

3. 나의코드

 

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

int N, M;
int K,r,s;
int doublearr[51][51]; //본 2차원 배멸 (변화 x)
int caculdoublearr[51][51]; //case별 결과값을 뽑아내기 위한 배열
int copydoublearr[51][51]; //이동을 위해 값을 복사해놓을 임시배열
bool check[51][51];
bool selected[7];
vector<int> resultmin;

struct rcs {
	int r,c,s;
};
vector<rcs> command; //입력받은명령
vector<rcs> casecommand; // 각 경우의수 (시뮬레이션 돌릴)

void input() { // 입력받는 함수		
	cin >> N >> M >> K;
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= M; j++) {
			cin >> doublearr[i][j];
		}
	}
	rcs tmp;
	for (int i = 0; i < K; i++) {
		cin >> tmp.r >> tmp.c >> tmp.s;
		command.push_back(tmp);
	}
}
void copyarr() { // 원본배열은 그대로 두고 복사해서 사용 (각 테스트케이스마다 써야하므로)
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= M; j++) {
			copydoublearr[i][j] = doublearr[i][j];
			caculdoublearr[i][j] = doublearr[i][j];
		}
	}
}
void initcheck() { // 방문배열 초기화
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= M; j++) {
			check[i][j] = false;
		}
	}
}
void copycal() { //한번회전한 배열을 계산을 위한 배열에 복사
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= M; j++) {
			copydoublearr[i][j] = caculdoublearr[i][j];
		}
	}
}
void turnarr(int r, int c, int s) { //회전을 구현
	int x = r - s;
	int y = c - s;
	int tmpcount = 0;
	int totalcount = 8 * s; //연산해야하는 횟수 한 바퀴에
	char dir = 'R';
	initcheck();
	while (1) {
		if (totalcount == tmpcount) { //바깥한바퀴 -> 안쪽 바퀴로 들어감
			x += 1; y += 1; s -= 1; totalcount = 8 * s;
			tmpcount = 0;
		}
		if (dir == 'R') {
			if (check[x][y+1] == true) { copycal(); break;
			}
			caculdoublearr[x][y + 1] = copydoublearr[x][y];
			tmpcount++;
			check[x][y] = true;
			y += 1;
			if (y == c + s) { dir = 'D'; }
		}
		else if (dir == 'D') {
			caculdoublearr[x + 1][y] = copydoublearr[x][y];
			tmpcount++;
			check[x][y] = true;
			x += 1;
			if (x == r + s) { dir = 'L'; }
		}
		else if (dir == 'L') {
			caculdoublearr[x][y - 1] = copydoublearr[x][y];
			tmpcount++;
			check[x][y] = true;
			y -= 1;
			if (y == c - s) { dir = 'U'; }
		}
		else {
			caculdoublearr[x - 1][y] = copydoublearr[x][y];
			tmpcount++;
			check[x][y] = true;
			x -= 1;
			if (x == r - s) { dir = 'R'; }
		}
	}
}
int getmin() { //배열의 최소값을 뽑아내는 함수
	int mini = 5001;
	for (int i = 1; i <= N; i++) {
		int tmpsum = 0;
		for (int j = 1; j <= M; j++) {
			tmpsum += caculdoublearr[i][j];
		}
		if (tmpsum < mini) { mini = tmpsum; }
	}
	return mini;
}
void relocating() { //명령을 수행 (회전명령)
	copyarr();
	for (int i = 0; i < K; i++) {
		turnarr(casecommand[i].r, casecommand[i].c, casecommand[i].s);
	}
	resultmin.push_back(getmin());
}
void simulation(int n) { //순열 경우의 수 생성
	if (n == K) {
		relocating(); 
		return;
	}
	for (int i = 0; i < command.size(); i++) {
		if (selected[i] == true) continue;
		selected[i] = true;
		casecommand.push_back(command[i]);
		simulation(n+1);
		casecommand.pop_back();
		selected[i] = false;
	}
}



int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
	input();
	simulation(0);
	sort(resultmin.begin(), resultmin.end());
	cout << resultmin[0];
	return 0;
}

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

백준 2033 C++  (0) 2020.11.25
백준 14890 [C++]  (0) 2020.10.21
백준 15686 [C++]  (0) 2020.10.17
백준 3190 [C++]  (0) 2020.10.17
백준 18406 [C++]  (0) 2020.10.16

www.acmicpc.net/problem/15686

 

15686번: 치킨 배달

크기가 N×N인 도시가 있다. 도시는 1×1크기의 칸으로 나누어져 있다. 도시의 각 칸은 빈 칸, 치킨집, 집 중 하나이다. 도시의 칸은 (r, c)와 같은 형태로 나타내고, r행 c열 또는 위에서부터 r번째 칸

www.acmicpc.net

 

1. 풀이방법

 

- 문제를 꼼꼼히 읽고, 전체 치킨 집 중에서 M개를 선택하는 경우의 수 (조합)

 

- 을 구해서 그 CASE마다 도시의 치킨거리를 구해보면 되는 문제.

 

 

 

2. 주의할점

 

- 딱히없음.

 

 

 

3.나의 코드

 

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

int N, M;
int map[51][51];
vector<pair<int, int>> chikenstore; //전체 치킨집을 저장할 좌표 집합
vector<pair<int, int>> chosenstore; //선택된 치킨집을 저장할 좌표 집합(M개)
vector<pair<int, int>> home; //집의 위치를 저장할 좌표 집합 (x,y) 
vector<int> result; //결과

void InputMap() { //입력받는 함수
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= N; j++) {
			cin >> map[i][j];
			if (map[i][j] == 2) {
				pair<int, int> tmp;
				tmp.first = i; tmp.second = j;
				chikenstore.push_back(tmp);
			}
			else if (map[i][j] == 1) {
				pair<int, int> tmp;
				tmp.first = i; tmp.second = j;
				home.push_back(tmp);
			}
		}
	}
}

int abs(int num1, int num2) { //절대값 반환
	if (num1 - num2 > 0) { return num1 - num2; }
	else { return num2 - num1; }
}

int loadsum(int x1, int y1, int x2, int y2) { //거리 계산
	return abs(x1, x2) + abs(y1, y2);
}

void caculatechickenload() { //도시의 치킨거리를 계산
	int sum = 0;
	for (int i = 0; i < home.size(); i++) { //집마다
		int min = 3000;
		for (int j = 0; j < chosenstore.size(); j++) { //치킨집에 대하여 거리계산(가장 가까운 치킨집=치킨거리)
			if (min > loadsum(home[i].first, home[i].second, chosenstore[j].first, chosenstore[j].second)) {
				min = loadsum(home[i].first, home[i].second, chosenstore[j].first, chosenstore[j].second);
			}
		}
		sum += min;
	}
	result.push_back(sum);
}

void Mchickenstore(int index) {
	if (chosenstore.size() == M) { // M개를 골랐다면 치킨거리계산 시작
		caculatechickenload();
		return;
	}
	for (int i = index; i < chikenstore.size(); i++) { //조합 경우의 수
		chosenstore.push_back(chikenstore[i]);
		Mchickenstore(i + 1);
		chosenstore.pop_back();
	}
}
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
	cin >> N >> M;
	InputMap();
	Mchickenstore(0);
	sort(result.begin(), result.end()); //가장 최소 도시치킨거리 출력
	cout << result[0] << "\n";
	
	return 0;
}

 

 

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

백준 2033 C++  (0) 2020.11.25
백준 14890 [C++]  (0) 2020.10.21
백준 17406 [C++]  (0) 2020.10.18
백준 3190 [C++]  (0) 2020.10.17
백준 18406 [C++]  (0) 2020.10.16

+ Recent posts