https://www.acmicpc.net/problem/1920

 

1920번: 수 찾기

첫째 줄에 자연수 N(1 ≤ N ≤ 100,000)이 주어진다. 다음 줄에는 N개의 정수 A[1], A[2], …, A[N]이 주어진다. 다음 줄에는 M(1 ≤ M ≤ 100,000)이 주어진다. 다음 줄에는 M개의 수들이 주어지는데, 이 수들

www.acmicpc.net

1. 풀이방법

- N개의 수중에 주어지는 M개의 수들이 각각 존재하는 지 확인해야합니다

 

- 선형탐색을 진행할 경우 O(N*M) 이므로 약 10,000,000,000 는 시간초과에 걸릴 것 같습니다.

 

- O(NlogN) 정렬 + O(M*logN) 이분탐색 으로 해결했습니다.

 

 

 

2. 주의사항

- 조건으로 인한 시간초과

 

 

3. 나의코드

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

int Narr[100000];
int N, M;
bool existnum(int target) {
	int ep = N - 1;
	int sp = 0;
	int mid;
	while (sp<=ep) {
		mid = (sp + ep) / 2;
		if (Narr[mid] == target) { return true; }
		else if (Narr[mid] < target) {
			sp = mid + 1;
		}
		else if (Narr[mid] > target) {
			ep = mid - 1;
		}
	}
	return false;
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	
	cin >> N;
	for (int i = 0; i < N; i++) {
		cin >> Narr[i];
	}
	sort(Narr, Narr+N); //이분탐색을 위한 정렬
	cin >> M;
	int target;
	for (int i = 0; i < M; i++) {
		cin >> target;
		cout << existnum(target)<<"\n";
	}
	return 0;
}

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

백준 2003 [C++]  (0) 2021.09.19
백준 3079 [C++]  (0) 2021.01.27
백준 2776 [C++]  (0) 2021.01.27
백준 2792 [C++]  (0) 2021.01.26
백준 1254 [C++]  (0) 2021.01.15

www.acmicpc.net/problem/2792

 

2792번: 보석 상자

보석 공장에서 보석 상자를 유치원에 기증했다. 각각의 보석은 M가지 서로 다른 색상 중 한 색상이다. 원장 선생님은 모든 보석을 N명의 학생들에게 나누어 주려고 한다. 이때, 보석을 받지 못하

www.acmicpc.net

1. 풀이방법

 

- 구현 문제를 많이 풀다보니 이런문제를 처음 봤을 때, 조금 당황스러웠습니다...;

 

- 어쨋든 최소질투심을 유발하게끔 나눠주는 방법은 1과 최대보석의 수 중에 있을 것이니까

 

- 이분 탐색을 통해 그것을 탐색해가면서 mid의 값이 아이들에게 조건에 맞게 나누어 줄 수 있는지 확인.

 

- 나누어 줄 수 있으면 더 작은 질투심을 유발할 수 있는 값이 있는지 mid보다 작은 쪽을 탐색.

 

- 아니라면 mid보다 큰 쪽을 탐색.

 

- 최소값을 출력하여 주었습니다.

 

 

2. 주의사항

 

- 없음.

 

 

3. 나의코드

#include<bits/stdc++.h> 
using namespace std;

long long n, m;
long long numarr[300001];
long long result = 1e18;

bool canspread(long long mid) {
    long long num = 0;
    for (int i = 0; i < m; i++) {
        num += numarr[i] / mid;
        if (numarr[i] % mid) num++;
    }
    return n >= num;
}
int main() {
    cin >> n >> m;
    long long left = 1; long long right = 0;
    for (int i = 0; i < m; i++) {
        cin >> numarr[i];
        if (right < numarr[i]) right = numarr[i];
        }
    while (left <= right) {
        long long mid = (left + right) / 2;
        if (canspread(mid)) {
            if (result > mid) result = mid;
            right = mid - 1;
        }
        else left = mid + 1;
    }
    cout << result << "\n";
    return 0;
}

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

백준 3079 [C++]  (0) 2021.01.27
백준 2776 [C++]  (0) 2021.01.27
백준 1254 [C++]  (0) 2021.01.15
백준 6064 [C++]  (0) 2020.11.30
백준 10815 [C++]  (0) 2020.10.25

www.acmicpc.net/problem/10799

 

10799번: 쇠막대기

여러 개의 쇠막대기를 레이저로 절단하려고 한다. 효율적인 작업을 위해서 쇠막대기를 아래에서 위로 겹쳐 놓고, 레이저를 위에서 수직으로 발사하여 쇠막대기들을 자른다. 쇠막대기와 레이저

www.acmicpc.net

1. 풀이방법

 

- 문제가 요구하는 사항을 구현하는 문제인데, 스택을 이용해서 현재 몇개의 막대가 쌓여있는지를 확인하였습니다.

 

- 사실 굳이 STACK.SIZE()를 그냥 임의의 변수 하나를 만들어 관리하면 그냥 반복문만으로도 구현 가능합니다.

 

 

 

2. 주의사항

 

- 조각의 개수가 증가하는 경우는 두가지 경우입니다. 

 

- (1) 레이저가 자르는 경우 (2) 막대가 끝나는 경우

 

 

 

3. 나의코드

<stack이용>

#include<iostream>
#include<stack>
#include<algorithm>
#include<vector>
#include<queue>
#include<string>
using namespace std;
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	string s;
	cin >> s;
	stack<char> sarr;
	int resultnum = 0;
	for (int i = 0; i < s.length(); i++) {
		if (sarr.empty()) { //비어있을 경우
			sarr.push(s[i]); continue;
		}
		if (s[i] == ')'&&s[i-1]== '(') { //레이저
			sarr.pop();
			resultnum += sarr.size();
			continue;
		}
		if (s[i] == '(') { //막대의 시작
			sarr.push(s[i]);
		}
		else if (s[i] == ')') { //막대의 끝
			sarr.pop();
			resultnum++;
		}
	}
	cout << resultnum << "\n";
	return 0;
}

<변수로 관리>

#include<iostream>
#include<string>

	using namespace std;

	int main() {
		int cnt = 0, result = 0;
		string t;
		cin >> t;
		for (int i = 0; i < t.length(); i++) {
			if (t[i] == '(') {
				if (t[i + 1] == ')') {
					i++;
					result += cnt;
					continue;
				}
				cnt++;
			}
			else {
				cnt--;
				result++;
			}
		}
		cout << result;
		return 0;
	}

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

백준 1406 [C++]  (0) 2021.01.09
백준 1874 [C++]  (0) 2021.01.09
백준 3986  (0) 2020.03.02
백준 2493  (0) 2020.01.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