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

 

15828번: Router

인터넷을 사용하기 위해서는 컴퓨터에 인터넷 회선을 연결하거나 Wi-Fi를 연결해야 한다. 이렇게 연결된 네트워크를 통해 컴퓨터에는 통신이 가능하다. 마음에 드는 노래나 동영상이 있는 곳에

www.acmicpc.net

 

#include <cstdio>
#include <queue>

using namespace std;

// 라우터

int main()
{
	queue<int> q;

	int n;
	scanf("%d", &n);

	int packet = 0;
	int packet_size = 0;

	while (packet != -1)
	{
		scanf("%d", &packet);

		if (packet == 0)
		{
			q.pop();
			packet_size = q.size();
		}
		else if (packet == -1)
		{
			break;
		}
		else
		{
			if (q.size() < n)
			{
				q.push(packet);
				packet_size += 1;
			}
		}
	}

	if (packet_size == 0)
	{
		printf("empty");
		return;
	}

	for (int i = 0; i < packet_size; ++i)
	{
		printf("%d\n", q.front());
		q.pop();
	}
}

 

 

..원래 C++로 풀었는데 똑같은 코드임에도 C++로 제출할 때는 시간초과가 뜨는데 C로 제출하니 100점이라고 떴다.

이전에 개행이나 print같은 부분에서 C가 훨씬 빨라서 C++과 제출 시간의 차이가 있었는데 얘도 마찬가지여서 그랬나. 

테스트 케이스가 너무 궁금하다. 

 

 

2742번: 기찍 N (acmicpc.net)

 

2742번: 기찍 N

자연수 N이 주어졌을 때, N부터 1까지 한 줄에 하나씩 출력하는 프로그램을 작성하시오.

www.acmicpc.net

 

..이 문제를 잊지 않기 위해서 포스팅하기로 했다.

 

#include <iostream>
using namespace std;
int N;
int main()
{
	cin >> N;
	for (int i = 0; i < N; ++i)
	{
		//cout << N - i << '\n';
		printf("%d\n", N - i);
	}
}

 

슥 채우고 넘어가려고 했는데 실패가 떠서 요근래 가장 당황스러웠다. 

100,000를 출력할 때 확실히 시간이 오래걸리긴 했다.

 

왜 자꾸 시간초과가 날까 검색해보다가 

cout, cin, endl가 printf나 '\n'보다 연산이 오래걸려서 그렇다고 했다.

그래서 그 출력 한줄 바꿔줬더니 4초만에 완료됐다.

나는 습관적으로 cin, cout을 사용하니까 다음에 시간초과 나거나 할 때 출력부분을 의심해 볼 만도 한 것 같다.

그리고 뭔가 입력과 출력에 대한 부분을 다시 깊게 찾아보는 것도 좋은 방법인 것 같다. 

 

11047번: 동전 0 (acmicpc.net)

 

11047번: 동전 0

첫째 줄에 N과 K가 주어진다. (1 ≤ N ≤ 10, 1 ≤ K ≤ 100,000,000) 둘째 줄부터 N개의 줄에 동전의 가치 Ai가 오름차순으로 주어진다. (1 ≤ Ai ≤ 1,000,000, A1 = 1, i ≥ 2인 경우에 Ai는 Ai-1의 배수)

www.acmicpc.net

 

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

int N, K;
vector<int> value;
int func()
{
	int answer = 0;
	int i = N-1;
	do {
		answer += (K / value[i]);
		K %= value[i];
		--i;
	} while (i >= 0);

	return answer;
}

int main()
{
	cin >> N >> K;
	int temp = 0;
	for (int i = 0; i < N; ++i)
	{
		cin >> temp;
		value.push_back(temp);
	}
	cout << func();
}

 

Greedy 알고리즘 문제로 간단하게 풀 수 있는 문제이다.

완전탐색을 진행하더라도 N번. 즉 10번만 돌면 되기 때문에 시간복잡도가 O(N)이다.

 

더보기

요즘 자꾸 주어진 케이스가 1개일 때 예외처리를 자꾸 빼먹는다. 문제 풀기 전에는 분명 꼭 1개일 때도 고려해야된다고 세번씩 다짐하지만 어느순간 잊는다.그래서 맨 위에 앞으로 주석으로 // N = 1개 일 때? 라고 추가하기로 했다.절대 안 볼 수 없게 특수문자 왕창 넣어 놔야지

 

1302번: 베스트셀러 (acmicpc.net)

 

1302번: 베스트셀러

첫째 줄에 오늘 하루 동안 팔린 책의 개수 N이 주어진다. 이 값은 1,000보다 작거나 같은 자연수이다. 둘째부터 N개의 줄에 책의 제목이 입력으로 들어온다. 책의 제목의 길이는 50보다 작거나 같고

www.acmicpc.net

 

map을 이용해서 입력받은 책의 이름들을 key값으로 넣어주었다. 

이렇게 하면 문제는 출력할 때 동일 우선순위(=value가 같을 때)에서 알파벳 순서대로 출력할 때 발생하게 된다.

그래서 map의 value값과 key값을 따로 정렬해주었다.

 

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

int N;
map<string, int> m;

bool cmp(const pair<string, int> &a, const pair<string, int> &b)
{
	if (a.second == b.second)
	{
		return a.first < b.first;
	} 
	return a.second > b.second;
}


int main()
{
	cin >> N;

	string temp;
	for (int i = 0; i < N; ++i)
	{
		cin >> temp;
		m[temp] += 1;
	}

	vector<pair<string, int>> vec(m.begin(), m.end());
	sort(vec.begin(), vec.end(), cmp);

	cout << vec[0].first;
}

1475번: 방 번호 (acmicpc.net)

 

1475번: 방 번호

첫째 줄에 다솜이의 방 번호 N이 주어진다. N은 1,000,000보다 작거나 같은 자연수 또는 0이다.

www.acmicpc.net

 

6과 9를 바꿔서 사용할 수 있으므로 0~8까지만 체크하고 그거에 대한 예외처리들만 해줬다.

 

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

int roomNumber;

int func()
{
	int temp = 0;
	vector<int> number;
	number.resize(9); // 0~8까지 체크

	do
	{
		temp = roomNumber % 10;
		if (temp == 9)
			number[6] += 1;
		else
			number[temp] += 1;
		roomNumber /= 10;
	} while (roomNumber >= 1);
	

	number[6] % 2 ? number[6]++ : 0;
	number[6] /= 2;

	sort(number.begin(), number.end(), greater<int>());

	return number[0];
}


int main()
{
	cin >> roomNumber;
	cout << func();
}

 

 

쉬워보이기도 했고 금방 풀어서 제출했는데 안되길래 0일 때도 해보고 이것저것 해봤는데

while문 조건에 number >= 1 를 해줘야 되는데 그냥 >만 해줘서 1199를 했을 때 두 세트가 아닌 한 세트가 출력되고 있었다. 

간만에 풀어서 그런가 또 초심을 잃었다.. 

 

www.acmicpc.net/problem/13904

 

13904번: 과제

예제에서 다섯 번째, 네 번째, 두 번째, 첫 번째, 일곱 번째 과제 순으로 수행하고, 세 번째, 여섯 번째 과제를 포기하면 185점을 얻을 수 있다.

www.acmicpc.net

 

 

우선 입력받은 데이터를 점수를 기반으로 정렬했다. 

vector의 second에 점수가 first에 과제 제출 기한이 담겨있다. 

 

탐욕법을 이용해서 푸는 문제로 점수를 기준으로 가장 큰 수부터 마감일에 가깝게 넣는다. 

오름차순으로 정렬된 벡터의 값에서 0번은 (한 번 돌릴 때마다 erase를 해주므로) 제일 점수가 큰 값이다.

따라서 0번을 뽑아서 해당 마감일에 이미 다른 점수가 있으면 전 날, 전전날을 계속 찾아본다.

비어있는 날이 있다면 해당 날짜에 넣고 없다면 버린다. 

 

 

왜 계속 틀렸을까 고민했던 문제이다. 그래서 이것저것 잘못 생각한 게 있었나 고민해봤지만 답이 나오지 않았다. 

그럴 수 밖에.. 틀린 이유는 따로 있었다.

밑에 answer에 더해주는 for문에서 n의 범위값을 틀려서 계속 채점 오류가 발생했다.

 

 

#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
bool cmp(const pair<int, int> &a, const pair<int, int> &b) 
{
	if (a.second == b.second)
	{
		return a.first < b.first;
	}
	return a.second > b.second;
}

int max_score(vector<pair<int, int>>& v, int &n)
{
	vector<int> tempv;
	tempv.resize(1001);
	int idx = 0;
	int answer = 0;
	while (idx < n) {

		for (int i = v[0].first; i > 0; --i)
		{
			if (tempv[i] != 0)
			{
				continue;
			}
			else
			{
				tempv[i] = v[0].second;
				break;
			}
		}

		idx += 1;
		v.erase(v.begin());
	}

	for (int i = 0; i <=1000; ++i)
	{
		answer += tempv[i];
	}
	return answer;
}


int main()
{
	vector<pair<int, int>>  v;
	int n;
	cin >> n;

	for (int i = 0; i < n; i++)
	{
		int n1, n2;
		cin >> n1 >> n2;
		v.push_back(make_pair(n1, n2));
	}
	sort(v.begin(), v.end(), cmp);
	int answer = max_score(v, n);
	cout << answer;
    
    return 0;
}

 

 

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

 

11279번: 최대 힙

첫째 줄에 연산의 개수 N(1≤N≤100,000)이 주어진다. 다음 N개의 줄에는 연산에 대한 정보를 나타내는 정수 x가 주어진다. 만약 x가 자연수라면 배열에 x라는 값을 넣는(추가하는) 연산이고, x가 0이라면 배열에서 가장 큰 값을 출력하고 그 값을 배열에서 제거하는 경우이다. 입력되는 자연수는 2^31보다 작다.

www.acmicpc.net

 

 

 

 

 

 

계속 시간초과 오류가 발생하였다.

 

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

int main()
{
	int N;
	cin >> N;
	vector<int> arr;
	arr.reserve(N);

	for (int i = 0; i < N; i++)
	{
		int temp = 0;
		cin >> temp;

		if (temp == 0)
		{
			if (!arr.empty())
			{
				sort(arr.begin(), arr.end(),greater<int>());
				cout << arr[0] << "\n";
				arr.erase(arr.begin());
			}
			else
			{
				cout << "0" << "\n";

			}
		}
		else {
			arr.push_back(temp);
		}
	}
}

 

 

이게 처음에 작성한 코드이고 시간초과가 계속 발생해서 우선순위 큐로 바꿔봐야 하나?

하고 우선순위 큐로 다시 작성한 코드가 아래 코드이다.

 

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

int main()
{
	int N;
	cin >> N;
	priority_queue<int> arr;


	for (int i = 0; i < N; i++)
	{
		int temp;
		cin >> temp;

		if (temp == 0)
		{
			if (!arr.empty())
			{
				cout << arr.top() << "\n";
				arr.pop();
			}
			else
			{
				cout << "0\n";
			}
		}
		else {
			arr.push(temp);
		}
	}
	return 0;
}

1번에서는 6%대에서 2번에서는 31%대에서 시간초과 오류가 계속 발생한다.

어디서 뭘 더 어떻게 줄여야 하는지 잘 모르겠다; 

 

혹시 몰라서 C++14로 체크하던걸 C++11으로 바꿨지만 여전히 똑같았다.

우선순위 큐로도 해결되지 않는다면 이건 대체 어떻게 풀어야 하는 걸까... 

정말 문제 제목대로 힙을 구현해야만 해결할 수 있는 문제인가?

근데 아무리 그래도 우선순위 큐로 구현한 것도 시간초과가 뜨나? 

 

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

 

7576번: 토마토

첫 줄에는 상자의 크기를 나타내는 두 정수 M,N이 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M,N ≤ 1,000 이다. 둘째 줄부터는 하나의 상자에 저장된 토마토들의 정보가 주어진다. 즉, 둘째 줄부터 N개의 줄에는 상자에 담긴 토마토의 정보가 주어진다. 하나의 줄에는 상자 가로줄에 들어있는 토마토의 상태가 M개의 정수로 주어진다. 정수 1은 익은 토마토, 정수 0은 익지 않은 토마토, 정수 -1은 토마

www.acmicpc.net

 

 

BFS로 풀면 되는 문제이다. 

우선 토마토에 대한 정보를 입력받고 

	for (int i = 0; i < h; i++)
	{
		for (int j = 0; j < w; j++)
		{
			if (arr[i][j] == 1) {
				check[i][j] = true;
				q.push(make_pair(i, j));
			}
		}
	}

처음에 전체 토마토 상자를 보면서 안에 익은 토마토가 어느 위치에 있는지 찾고 queue에 넣어주었다.

 

그후 while문으로 들어가서 현재 queue의 size만큼 for문을 돌려주면서 해당 위치의 동, 서, 남, 북의 칸을 비교해서

익지 않은 토마토(arr[y][x] == 0)이며 방문하지 않았으면(check[y][x] == false) queue에 넣고 방문했다는 표시를 한다.

 

for (int i = 0; i < h; i++)
	{
		for (int j = 0; j < w; j++)
		{
			if (arr[i][j] == 0 && check[i][j] == false)
			{
				return -1;
			}
		}
	}

이 부분은 처음에 런타임 에러도 발생하고 채점 결과가 틀렸다고 계속 나와서

Visual studio에서 예제를 돌렸을 때는 문제가 없어서 뭐가 문제인지 한참 고민하다가 

예를 들면 3x3 에서

0 -1 -1
-1 1 1
1 1 1

이렇게 예상치 못한 상황에서 익지 못하게 되는 토마토를 확인하기 위해서 추가하게 되었다. 

 

#include <iostream>
#include <queue>

using namespace std;
const int MAX_BOX = 1000;
int dirX[4] = { 1, -1, 0, 0 };
int dirY[4] = { 0,0,-1,1 };
bool check[MAX_BOX + 1][MAX_BOX + 1];

int tomato(int **arr, int w, int h)
{
	int day = 0;
	queue<pair<int, int>> q;

	// 처음에 넘겨받은 토마토 상자 안에 익은 토마토가 몇 개나 있는지 
	for (int i = 0; i < h; i++)
	{
		for (int j = 0; j < w; j++)
		{
			if (arr[i][j] == 1) {
				check[i][j] = true;
				q.push(make_pair(i, j));
			}
		}
	}

	while (!q.empty())
	{
		int q_size = q.size();
		for (int j = 0; j < q_size; j++) {

			int y = q.front().first;
			int x = q.front().second;

			q.pop();

			for (int i = 0; i < 4; i++)
			{
				int tempy = y + dirY[i];
				int tempx = x + dirX[i];

				if ((tempy < h && tempy >= 0) && (tempx >= 0 && tempx < w)) {
					if (arr[tempy][tempx] == 0 && check[tempy][tempx] == false)
					{
						check[tempy][tempx] = true;
						q.push(make_pair(tempy, tempx));
					}
				}
			}
		}
		day += 1;
	}

	// 다 돌아봤을 때 익지 않은 토마토가 존재하면서 그곳에 방문하지 않은 경우가 있는지 확인
	for (int i = 0; i < h; i++)
	{
		for (int j = 0; j < w; j++)
		{
			if (arr[i][j] == 0 && check[i][j] == false)
			{
				return -1;
			}
		}
	}
	return day - 1;
}

int main()
{
	int w, h;
	cin >> w >> h;

	// 배열
	int **box = new int*[h];
	for (int i = 0; i < h; i++)
	{
		box[i] = new int[w];
	}

	// 입력받기
	for (int i = 0; i < h; i++)
	{
		for (int j = 0; j < w; j++)
		{
			cin >> box[i][j];
		}
	}
	cout << tomato(box, w, h);
	return 0;
}

 

 

+ Recent posts