www.acmicpc.net/problem/1837

 

1837번: 암호제작

원룡이는 한 컴퓨터 보안 회사에서 일을 하고 있다. 그러던 도중, 원룡이는 YESWOA.COM 으로부터 홈페이지 유저들의 비밀키를 만들라는 지시를 받았다. 원룡이는 비밀 키를 다음과 같은 방법으로

www.acmicpc.net

1. 풀이방법

 

- 첫번째는 소수 판별과 두번째는 longlong 범위를 넘어가는 big integer에 대한 mod연산 구현

 

- 이 두가지를 구현하는 문제 인데 첫번째는 에라토스테네스의 채를 이용하여 소수 set을 만들었고 (k의최대값까지)

 

- string으로 큰수를 받아서 (10^100 이므로) c++에서 제공하는 정수를 담는 자료형으로는 어림도 없으므로

 

- 그 문자열로 받은 큰 수를 int로 나누어보는 함수를 구현하였다 (나누는 수는 k보다 작으므로 int 가능)

 

 

 

 

2. 주의사항

 

- 제 구현에서는 소수 set을 만드는 부분과 나누어지는지 확인하는 부분이 나누어져있지만

 

- 짜고 나서 보니 에라토스테네스의 체를 이용하여 구해가면서 그때그때 판별을 하면 연산의 수를 줄일 수 있을

 

- 것 같습니다.

 

 

 

 

3. 나의코드

 

#include<bits/stdc++.h>
using namespace std;
const int maxk= 1e6+1;

bool isitprime[maxk]; //false 이면 소수
string ps;
int k;
int resulti = 0;

void makeprimeset() { //소수 판별
	isitprime[0] = true; isitprime[1] = true;
	for (int i = 2; i <= k; i++) {
		if (isitprime[i] == false) { //소수이면
			int index = i;
			int tmp = 2;
			while (index * tmp <= k) { //배수는 모두 소수가 아님
				isitprime[index * tmp] = true;
				tmp++;
			}
		}
	}
}
bool bigintdivide(int p) {
	int tmpsum = 0;
	for (int i = 0; i < ps.length(); i++) {
		tmpsum = (tmpsum * 10 + (ps[i] - '0'))%p; //앞자리수 부터
	}
	if (tmpsum == 0) return true;
	else return false;
}

bool isunderk() {
	for (int i = 2; i <k; i++) {
		if (isitprime[i] == false) {
			if (bigintdivide(i)) {
				resulti = i; return false;
			}
		}
	}
	return true;
}

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

	makeprimeset(); //에라토스테네스의 채
	if (isunderk()) cout << "GOOD" << "\n";
	else cout << "BAD" << " " << resulti << "\n";


	return 0;
} 

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

백준 2609 [C++]  (0) 2020.12.03

www.acmicpc.net/problem/1600

 

1600번: 말이 되고픈 원숭이

첫째 줄에 정수 K가 주어진다. 둘째 줄에 격자판의 가로길이 W, 세로길이 H가 주어진다. 그 다음 H줄에 걸쳐 W개의 숫자가 주어지는데, 0은 아무것도 없는 평지, 1은 장애물을 뜻한다. 장애물이 있

www.acmicpc.net

 

1. 풀이방법

 

- 약간은 어려워진 BFS인 것 같습니다.

 

- 체스의 나이트 처럼 이동할 수 있는 가능 횟수가 오직 K번 이므로, K번 + 나머지 횟수는 4방향탐색

 

- 을 통해 가야하는데 DFS로 구현을 할 경우 시간이 부족합니다.

 

- 그래서 BFS로 다시 짜는데, 핵심이라고 생각되는 것은 만약에 K번 중 한번을 사용하여 점프를 뛰고

 

- 바로 거기를 방문처리를 해버리면 4방향탐색을 통해 그쪽에 도착한 후 나중에 말 처럼 점프하는 사항을

 

- 고려할 수 가 없습니다.

 

- 그래서 평소 이용하는 visit 이차원 배열을 k의 수만큼 삼차원 배열로 만들어서

 

- k 중 몇번을 써서 왔는지를 확인하고 k번을 써서 i,j에 도착했을 경우 방문처리를 해줍니다.

 

- 만약 i,j로 왔는데 k를 한번도 사용하지 않고 왔다면 그 전에 i,j에 왔으나 k를 한번 써서 방문한 경우가 있어도

 

- 다시 큐로 들어가게끔 구현하였습니다.

 

 

 

2. 주의사항

 

- visit 처리

 

 

 

3. 나의코드

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

int k, w, h;
int chesspan[200][200];
bool visit[200][200][31]; //k는 0~30
int horsemovex[8] = { -1,-2,-2,-1,1,2,2,1 };
int horsemovey[8] = { -2,-1,1,2,2,1,-1,-2 };
int dx[4] = { 0,0,1,-1 }; //k번을 다 소모했을 경우
int dy[4] = { 1,-1,0,0 };
int s = 0;
int mincount = 99999999;
bool fail = false;
struct xyk {
	int x, y, kn,s;
};
queue<xyk> tmpq;

void inputs() { //1은 장애물
	cin >> k >> w >> h;
	for (int i = 0; i < h; i++) {
		for (int j = 0; j < w; j++) {
			cin >> chesspan[i][j];
		}
	}
}
bool boundcheck(int x, int y) {
	if (x >= 0 && x < h && y >= 0 && y < w) return true;
	else return false;
}
int bfs() {
	while (1) {
		int qsize = tmpq.size();
		while (qsize--) {
			if (tmpq.empty()) { fail = true; return 0; }
			int nextx = tmpq.front().x;
			int nexty = tmpq.front().y;
			int nextk = tmpq.front().kn;
			int nexts = tmpq.front().s;
			tmpq.pop();
			if (nextx == h - 1 && nexty == w - 1) { 
				return nexts; }
			if (nextk != 0) {
				for (int i = 0; i < 8; i++) {
					int tx = nextx+ horsemovex[i]; int ty =nexty+ horsemovey[i];
					if (boundcheck(tx, ty) && visit[tx][ty][nextk-1] == false && chesspan[tx][ty] != 1) {
						tmpq.push({ tx,ty,nextk - 1,nexts +1 });
						visit[tx][ty][nextk-1] = true;
					}
				}
			}
			for (int i = 0; i < 4; i++) {
				int tx2=nextx +dx[i]; int ty2 =nexty+ dy[i];
				if (boundcheck(tx2, ty2) && visit[tx2][ty2][nextk] == false && chesspan[tx2][ty2] != 1) {
					tmpq.push({ tx2,ty2,nextk,nexts +1 });
					visit[tx2][ty2][nextk] = true;
				}
			}
		}
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	inputs();
	tmpq.push({ 0,0,k,0 });
	//출발점은 0,0 도착점은 h-1,w-1
	int r=bfs();
	if (fail == true) { cout << -1 << "\n"; }
	else cout <<r << "\n";


	return 0;
}

'알고리즘 문제풀이 > DFS와 BFS' 카테고리의 다른 글

백준 15900 [C++]  (0) 2021.01.19
백준 2251 [C++]  (0) 2021.01.19
백준 12851 [C++]  (0) 2021.01.18
백준 13913 [C++]  (0) 2021.01.18
백준 19238 [C++]  (0) 2021.01.17

www.acmicpc.net/problem/12851

 

12851번: 숨바꼭질 2

수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때

www.acmicpc.net

1. 풀이방법 

 

- 숨바꼭질 4를 풀었다고 만만하게 덤볐다가 큰 코 다친 문제입니다..

 

- 문제를 많이 풀다보면 코드를 짤때 그 의미를 생각하지않고 항상 짜던데로 습관적으로 짜는 경향이 있는데,,,,

 

- 50퍼 정도에서 틀렸습니다 가 계속 나와서 질문검색에서 도움을 받았습니다.

 

-www.acmicpc.net/board/view/22749

 

글 읽기 - 12851번 숨바꼭질2 오답이 될만한 입력값

댓글을 작성하려면 로그인해야 합니다.

www.acmicpc.net

- 이분의 글을 보고 도움을 받았습니다.

 

- 제가 틀린 부분을 찾은 예시는

 

- 1 4

  입력시

  2

  2

(저는 1이 나왔었습니다)

- 였습니다.

 

-  1 -> 1+1 -> (1+1) * 2 (여기서 만약 2를 체크하면)

   1 -> 1*2 -> (1*2) * 2 (이 예시가 케이스로 들어가지 않음)

 

- 그래서 이 문제에서는 BFS를 돌때 큐에 넣을 때 VISIT을 체크하는 것이 아니라 큐에서 뺄 때 VISIT을 체크했습니다.

 

- 그외에는 K를 발견하면 그때의 큐를 끝까지 다 보는 방식으로 구현했습니다.

 

 

 

2. 주의사항

 

- 의미를 항상 생각하며 코드를 짜자!

 

 

 

3. 나의코드

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

int n, k;
int resultcount;
bool visit[100001];
queue<int> tmpq;
vector<int> tmpv;
int second = 1;
int nextn;
int qsize;
bool suc = false;
void checkrest() {
	while (qsize--) {
		nextn = tmpq.front(); tmpq.pop();
		if (nextn + 1 <= 100000 && nextn + 1 == k) resultcount++;
		if (nextn - 1 >= 0 && nextn - 1 == k) resultcount++;
		if (nextn * 2 <= 100000 && nextn * 2 == k) resultcount++;
	}
}

void bfs() {	
	while (1) {
		tmpv.clear();
		qsize = tmpq.size();
		while (qsize--) {
			nextn = tmpq.front();
			tmpq.pop();
			visit[nextn] = true;
			tmpv.push_back(nextn);
			
			//1증가
			if (nextn + 1 <= 100000 && visit[nextn + 1] == false) {
				tmpq.push(nextn + 1);
				if (nextn+1 == k) {
					resultcount++;
					checkrest();
					return; }
			}

			if (nextn - 1 >= 0 && visit[nextn - 1] == false) {
				tmpq.push(nextn - 1);
				if (nextn-1 == k) {
					resultcount++;
					checkrest();
					return; }
			}

			if (nextn * 2 <= 100000 && visit[2 * nextn] == false) {
				tmpq.push(nextn * 2);
				if (nextn*2 == k) {
					resultcount++;
					checkrest();
					return; }
			}
		}
		second++;
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> n >> k;
	if (n >= k) {
		cout << n - k << "\n";
		cout << 1 << " ";
	}
	else {
		tmpq.push(n);
		visit[n] = true;
		bfs();
		cout << second << "\n" << resultcount << "\n";
	}
	return 0;
}

'알고리즘 문제풀이 > DFS와 BFS' 카테고리의 다른 글

백준 2251 [C++]  (0) 2021.01.19
백준 1600 [C++]  (0) 2021.01.19
백준 13913 [C++]  (0) 2021.01.18
백준 19238 [C++]  (0) 2021.01.17
백준 17142 [C++]  (0) 2021.01.17

www.acmicpc.net/problem/19238

 

19238번: 스타트 택시

첫 줄에 N, M, 그리고 초기 연료의 양이 주어진다. (2 ≤ N ≤ 20, 1 ≤ M ≤ N2, 1 ≤ 초기 연료 ≤ 500,000) 연료는 무한히 많이 담을 수 있기 때문에, 초기 연료의 양을 넘어서 충전될 수도 있다. 다

www.acmicpc.net

1. 풀이방법

 

- BFS 활용문제 입니다.

 

- 문제의 조건이 좀 많고 , 주의하여야할 점이 좀 있는 문제였습니다.

 

- 일단 저 같은 경우 승객들의 출발지점은 모두 다르므로 승객의 도착점을 찾을 때는 

 

- 승객들 간의 분별이 가능한 출발점을 기준으로 찾았습니다 (그리고 그 찾은 승객의 INDEX를 통해서 도착점을 지정)

 

- 저같은 경우 첫 BFS 탐색을 통해 승객을 찾고 두번째 BFS를 통해 도착점을 찾았습니다.

 

- 승객을 찾아서 태우면 ground[i][j] =0  빈칸으로 바꿔주고 (한 칸에 두명 이상의 손님이 있는경우는 없으므로 상관 x)

 

- 도착점에 도착하면 그 도착점을 택시의 새로운 위치로 갱신하여 주었습니다.

 

 

 

 

2. 주의사항

 

- 도착점에서 손님을 내리고, 그곳에 손님이 있을경우 바로 태울 수 있다.

 

- 벽 때문에 도착하지 못하는 경우는 실패이다.

 

- 거리 > 행 > 열 순으로 승객을 특정한다.

 

- 승객을 찾으러 갈 때 연료가 부족하거나, 승객을 태우고 목적지로 가는 중 연료가 부족하면 실패이다.

 

- 그리고 "거리 > 행 > 열" 순으로 정렬을 하는 과정에서 실수가 있어 거의 한시간을 해맸는데..."

 

- 일단 2(즉, 승객) 을 찾으면 지금 현재 큐에 있는 승객들을 모두 벡터로 담아 소팅을 했는데

 

- 여기서 주석에서 보시다시피 while(!tmpq.empty()) 이런 실수를 했는데,

 

- 이럴경우 다음단계에 해당하는 녀석들도 큐에 들어가있는 상태 이므로 오류가 나옵니다.

 

- 보통 하나의 큐를 이용하여 bfs를 구현할 경우 한번의 반복문이 끝난후 그 큐의 size를 측정해서 하나의 단계로

 

- 취급하므로 이때도 while(ssize--)를 해야 했습니다.

 

 

 

3. 나의코드

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

int ground[21][21];
bool visit[21][21];
int n, m, fuel;
int texix, texiy;
int tmpx, tmpy;
//북서동남
int dx[4] = { -1,0,0,1 };
int dy[4] = { 0,-1,1,0 };
queue<pair<int, int>> tmpq;
bool fail = false;
int nextx, nexty;
int distances;
int ssize;
vector<pair<int,int>> tmpvector;

struct client {
	int sx, sy, ex, ey;
};
vector<client> clients;
bool compare(pair<int,int> &lhs, pair<int,int> &rhs) {
	if (lhs.first < rhs.first) return true;
	else if (lhs.first == rhs.first) {
		if (lhs.second < rhs.second) return true;
		else return false;
	}
	else return false;
}
void inputs() {
	cin >> n >> m>>fuel;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cin >> ground[i][j];
		}
	}
	cin >> texix >> texiy;
	texix -= 1; texiy -= 1;
	for (int i = 0; i < m; i++) {
		int x1, y1, x2, y2;
		cin >> x1 >> y1 >> x2 >> y2;
		ground[x1-1][y1-1] = 2;
		clients.push_back({ x1-1,y1-1,x2-1,y2-1 });
	}
}
void qclear() {
	while (!tmpq.empty()) {
		tmpq.pop();
	}
}
void visitclear() {
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			visit[i][j] = false;
		}
	}
}
bool boundcheck(int x, int y) {
	if (x < 0 || x >= n || y < 0 || y >= n) return false;
	else return true;
}

void bfs() {
	distances = 0;
	bool checking = false;
	while (1) {
		if (tmpq.empty()) { fail = true; return; }
		 ssize = tmpq.size();
		while (ssize--) {
			 nextx = tmpq.front().first;
			 nexty = tmpq.front().second;
			 tmpq.pop();
			if (ground[nextx][nexty] == 2) { //손님을 찾으면 break;
				tmpvector.clear();
				tmpvector.push_back({ nextx,nexty });
				while (ssize--) { //  !!!!!! (!tmpq.empty()) 하면 틀림
					int ttx = tmpq.front().first;
					int tty = tmpq.front().second;
					tmpq.pop();
					if (ground[ttx][tty] == 2) {
						tmpvector.push_back({ ttx,tty });
					}
				}
				sort(tmpvector.begin(), tmpvector.end(), compare);
				nextx = tmpvector[0].first;
				nexty = tmpvector[0].second;
				checking = true; break;
			}
			for (int i = 0; i < 4; i++) {
				int tx = nextx + dx[i]; int ty = nexty + dy[i];
				if (boundcheck(tx, ty) && visit[tx][ty] == false && ground[tx][ty] != 1) {
					visit[tx][ty] = true;
					tmpq.push({ tx,ty });
				}
			}
		}
		if (checking == true) { break; }
		distances++;
	}
	fuel -= distances; //이동한만큼 연료소모
	if (fuel < 0) { fail = true; return; }
	ground[nextx][nexty] = 0; // 손님을 태웠슴
	int clientindex = -1;
	for (int i = 0; i < clients.size(); i++) {
		if (clients[i].sx == nextx && clients[i].sy == nexty) {
			clientindex = i; break; //손님의 목적지를 알기위해
		}
	}
	visitclear();
	qclear();
	tmpq.push({ nextx,nexty }); //출발지점
	ground[nextx][nexty] = 0; //손님을 태움
	visit[nextx][nexty] = true;

	distances = 0;
	checking = false;
	while (1) {
		if (tmpq.empty()) { fail = true; return; }
		ssize = tmpq.size();
		while (ssize--) {
			nextx = tmpq.front().first;
			nexty = tmpq.front().second;
			tmpq.pop();
			if (nextx==clients[clientindex].ex &&nexty==clients[clientindex].ey) { //손님을 찾으면 break;
				checking = true; break;
			}
			for (int i = 0; i < 4; i++) {
				int tx = nextx + dx[i]; int ty = nexty + dy[i];
				if (boundcheck(tx, ty) && visit[tx][ty] == false && ground[tx][ty] != 1) {
					visit[tx][ty] = true;
					tmpq.push({ tx,ty });
				}
			}
		}
		if (checking == true) {break; }
		distances++;
	}
	fuel -= distances;
	if (fuel < 0) {
		fail = true; return;
	}
	texix = nextx; texiy = nexty; //택시 위치 변경
	fuel += (2 * distances);
}
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	inputs();
	for (int i = 0; i < m; i++) {
		qclear();
		visitclear();
		tmpq.push({ texix,texiy });
		visit[texix][texiy] = true;
		bfs();//손님찾자
		if (fail == true) { cout << -1 << "\n"; return 0; }
	}

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

'알고리즘 문제풀이 > DFS와 BFS' 카테고리의 다른 글

백준 12851 [C++]  (0) 2021.01.18
백준 13913 [C++]  (0) 2021.01.18
백준 17142 [C++]  (0) 2021.01.17
백준 16236 [C++]  (0) 2020.12.29
백준 2644 [C++]  (0) 2020.12.22

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/15659

 

15659번: 연산자 끼워넣기 (3)

첫째 줄에 수의 개수 N(2 ≤ N ≤ 11)가 주어진다. 둘째 줄에는 A1, A2, ..., AN이 주어진다. (1 ≤ Ai ≤ 100) 셋째 줄에는 합이 N-1인 4개의 정수가 주어지는데, 차례대로 덧셈(+)의 개수, 뺄셈(-)의 개수, 

www.acmicpc.net

1. 풀이방법

 

- 일단 숫자는 고정이고, 연산자만으로 모든 순열을 다 짜고 연산을 시작한다.

 

- 문제는 연산자 우선순위에 따른 계산을 해야한다는 것인데

 

- 저 같은경우 * 또는 / 먼저 연산을 완료한 후 새로운 벡터에 넣어놓고 그 후 + 또는 - 연산을 해주었습니다.

 

- 이과정에서 구현이 매우 까다로웠는데,

 

- 먼저 해야하는 것은 * 또는 / 가 나오는 경우 이 연산자들이 연속되어있는 곳 까지는 연산을 계속해줍니다.

(예를 들어 5+7*4*3-3) 이런 경우 *가 처음 등장하면 뒤쪽에 -가 나오기 전까지는 쭉 연결해서 연산을 해줍니다.

 

- 그후 덧셈, 뺄셈 연산을 수행하는데, 예외사항들이 많아 너무 복잡한 문제였습니다. 개인적으로......

 

- 저 말고는 제 코드를 이해하는 분이 계실지가..ㅋㅋㅋㅋ

 

 

 

 

2. 주의사항

 

- 테스트케이스를 보면서 수정해나가면서 짠 후 ,, 90퍼에서 계속 실패가 떠서 예외사항을 직접 찾아 해매야 했습니다.

 

 

 

 

3. 나의코드

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

int N,tmp;
vector<long long> numarr;
vector<long long> oper;
vector<long long> tmpoper;
long long maxresult = -9999999999;
long long minresult = 9999999999;
bool allplusorminus;

void inputs() {
	cin >> N;
	for (int i = 0; i < N; i++) { cin >> tmp; numarr.push_back(tmp); }
	for (int i = 0; i < 4; i++) { cin >> tmp; oper.push_back(tmp); }
}

int makenum() {
	vector<long long> tmparr;
	int index = 0;
	for (int i = 0; i < tmpoper.size(); i++) { //곱셈 나눗셈 먼저
		if (tmpoper[i] == 2 || tmpoper[i] == 3) {
			int tempint=numarr[index];
			while (1) { //연속되는 곱셈,나눗셈까지는 모두 같이 처리
				if (i == tmpoper.size() || tmpoper[i] == 0 || tmpoper[i] == 1) { index++; break; }
				if (tmpoper[i] == 2) { //곱셈
					tempint *= numarr[index + 1];
					index++;
				}
				else { //나눗셈
					tempint /= numarr[index + 1];
					index++;
				}
				i++;
			}
			tmparr.push_back(tempint);
			i--;
		}
		else { //아래와 같이 생각해줘야할 예외사항이 너무 많다.!!!!!!!!!!!!!!!
			if (i==0 || i == tmpoper.size() - 1){ 
				tmparr.push_back(numarr[index]); index++;
				if (tmpoper.size() == 1) tmparr.push_back(numarr[index]);
			}
			if (i < tmpoper.size() - 1 && (tmpoper[i + 1] == 0 || tmpoper[i + 1] == 1)) { 
				tmparr.push_back(numarr[index]);
				index++;
			}
		}
	}
	long long result=tmparr[0];
	index = 1;
	for (int i = 0; i < tmpoper.size(); i++) {
		if (tmpoper[i] == 0 || tmpoper[i] == 1) {
			if (tmpoper[i] == 0) { // 덧셈
				result += tmparr[index];
				index++;
			}
			else { //뺄셈
				result -= tmparr[index];
				index++;
			}
		}
	}
	return result;
}

void makecase(int cnt) {
	if (cnt == N - 1) {
		/*cout << numarr[0];
		for (int i = 0; i < tmpoper.size(); i++) {
			if (tmpoper[i] == 0) { cout << " + "; }
			if (tmpoper[i] == 1) { cout << " - "; }
			if (tmpoper[i] == 2) { cout << " * "; }
			if (tmpoper[i] == 3) { cout << " / "; }
			cout << numarr[i + 1];
		}
		cout << "\n";*/
		if (makenum() > maxresult) { maxresult = makenum(); }
		if (makenum() < minresult) { minresult = makenum(); }
		return;
	}
	for (int i = 0; i < 4; i++) {
		if (oper[i] != 0) {
			tmpoper.push_back(i);
			oper[i]--;
			makecase(cnt + 1);
			oper[i]++;
			tmpoper.pop_back();
		}
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	inputs();
	makecase(0);
	cout << maxresult << "\n" << minresult << "\n";
	return 0;
}

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

백준 2422 [C++] - 시간초과  (0) 2021.01.15
백준 18511 [C++]  (0) 2021.01.15
백준 9663 [C++]  (0) 2021.01.13
백준 1107 [C++]  (0) 2020.12.14
백준 14500 [C++]  (0) 2020.12.05

www.acmicpc.net/problem/1254

 

1254번: 팰린드롬 만들기

동호와 규완이는 212호에서 문자열에 대해 공부하고 있다. 규완이는 팰린드롬을 엄청나게 좋아한다. 팰린드롬이란 앞에서부터 읽으나 뒤에서부터 읽으나 같게 읽히는 문자열을 말한다. 동호는

www.acmicpc.net

1. 풀이방법

 

- 일단 처음 문제를 읽고 든 생각은 제일 길어봤자 문자열의 길이 *2 정도 이겠구나 였습니다.

   (뒤에서부터 차례대로 추가하면 되니까)

 

- 입력은 string으로 받아 편의를 위해 저는 vector<char>에 옮겨 담았습니다.

 

- 그리고 이제 하나씩 추가를 하고 이게 펠린드롬이 맞는지를 확인하였습니다.

 

- 반복문만 활용하면 잘 풀 수 있는 문제였습니다.

 

 

 

2. 주의사항

 

- 없음. 

 

 

 

3. 나의코드

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

string s;
vector<char> carr;
vector<char> tmpc;
int resultlen;

bool isitpelen() {
	for (int i = 0; i < tmpc.size() / 2; i++) {
		if (tmpc[i] != tmpc[tmpc.size() - 1 - i]) return false;
	}
	return true;
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> s;
	for (int i = 0; i < s.length(); i++) carr.push_back(s[i]);

	resultlen = s.length();
	tmpc = carr;
	if (isitpelen()){
		cout << resultlen << "\n"; return 0;
	}
	for (int i = 0; i < s.length(); i++) {
		tmpc = carr;
		for (int j = i; j >= 0; j--) {
			tmpc.push_back(s[j]);
			if (isitpelen()) {
				cout << resultlen + i + 1 << "\n"; return 0;
			}
		}
	}
	return 0;
}

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

백준 2776 [C++]  (0) 2021.01.27
백준 2792 [C++]  (0) 2021.01.26
백준 6064 [C++]  (0) 2020.11.30
백준 10815 [C++]  (0) 2020.10.25
최대공약수 구하기 (재귀,유클리드호제법)  (0) 2020.10.08

www.acmicpc.net/problem/1051

 

1051번: 숫자 정사각형

N*M크기의 직사각형이 있다. 각 칸은 한 자리 숫자가 적혀 있다. 이 직사각형에서 꼭짓점에 쓰여 있는 수가 모두 같은 가장 큰 정사각형을 찾는 프로그램을 작성하시오. 이때, 정사각형은 행 또는

www.acmicpc.net

1. 풀이방법.

 

- 모든 정사각형의 4개의 꼭지점이 같은지 확인해주시면 됩니다.

 

- 입력이 붙어있길래 전 char 배열을 선언해서 입력을 받았습니다.

 

- 숫자가 들어오지만 , 계산하는 과정은 없고 같은지만 확인하면 되므로 따로 숫자로 변환시키지는 않았습니다.

 

 

 

 

2. 주의사항

 

- 하나짜리도 정사각형 입니다. (어찌보면 당연)

 

- 전그냥 따로 예외로 빼주었습니다. 

 

 

 

3. 나의코드

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

int N, M;
char nemo[51][51]; //0~ n-1, 0 ~ m-1

int maxcnt = 0;

void inputs() {
	cin >> N >> M;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			cin >> nemo[i][j];
		}
	}
}
int samenemo(int x, int y, int c) {
	if (nemo[x][y] == nemo[x + c][y] && nemo[x][y] == nemo[x][y + c]
		&& nemo[x][y] == nemo[x + c][y + c]) return true;
	else return false;
}
void makecase(int cnt)
{
	for (int i = 0; i < N-cnt; i++) {
		for (int j = 0; j < M-cnt; j++) {
			if (samenemo(i, j,cnt)) {
				if (maxcnt < cnt) {
					maxcnt = cnt;
				}
			}
		}
	}
}
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	inputs();
	if (N == 1 || M == 1) { cout << 1 << "\n"; return 0; }
	for (int i = 1; i < min(N, M); i++) {
		makecase(i); // 시작 index와 한 변의 길이
	}
	cout << (maxcnt+1)*(maxcnt+1) << "\n";

	return 0;
}

 

+ Recent posts