안경잡이개발자

728x90
반응형

문제 유형: 수학

문제 URL: https://codeforces.com/contest/915/problem/A


  정원은 길이가 K인 선분(Segment) 형태로 표현됩니다. 또한 N개의 그릇에 물을 담아서 농작물에 물을 주려고 합니다. i번째 그릇은 한 시간에 Ai 길이의 연속적인 공간에 물을 줄 수 있도록 해줍니다. 이 때 한 번 물을 준 곳은 더 이상 주지 않으며 주인공은 하나의 그릇을 선택하여 가능한 빠르게 농사를 짓는 전체 공간에 물을 주고자 합니다. 이 때 주인공이 가장 적은 시간으로 정원에 물을 줄 때의 시간을 구하면 됩니다.


  이 문제는 길이가 K인 전체 정원에 물을 주어야 하며 남는 공간이 없어야 하고, 한 번 물을 준 곳은 더 이상 줄 수 없다는 점에서 단순히 약수를 판별하는 문제입니다. 주어진 그릇의 크기 중에서 K의 약수로 가장 큰 것을 고르면 됩니다. 따라서 K를 해당 약수로 나눈 값을 출력하도록 하면 정답 처리를 받을 수 있습니다. 또한 항상 하나 이상의 그릇은 정원의 모든 공간에 물을 줄 수 있도록 입력이 주어진다고 합니다.


※ 예시 입출력 ※

input
Copy
3 6
2 3 5
output
Copy
2
input
Copy
6 7
1 2 3 4 5 6
output
Copy
7


※ 정답 소스코드 ※

(컴파일 환경: GNU G++11 5.1.0)

#include <iostream>
#include <limits.h>

using namespace std;

int main(void) {
	int n, k;
	cin >> n >> k;
	int res = INT_MIN;
	for(int i = 0; i < n; i++) {
		int x;
		cin >> x;
		if(k % x == 0) {
			res = max(res, x);
		}
	}
	cout << k / res;
	return 0;
}


728x90
반응형

728x90
반응형

문제 유형: 구현

문제 URL: https://codeforces.com/contest/390/problem/A


  이 문제는 대표적인 단순 구현 문제입니다. 이 문제는 초기에 101 X 101 이차원 격자에 여러 개의 알람 시계가 있다고 가정합니다. 이 때 가로 혹은 세로에 있는 알람을 모두 한 번에 끌 수 있다고 합니다. 가로 혹은 세로 라인을 선택하는 최소 횟수를 구하면 됩니다.


  다만 알람을 끌 때 모두 가로로 끄거나, 모두 세로로 끄거나 둘 중 하나만 선택해야 합니다. 예를 들어 2번 가로 줄의 알람을 모두 끄고, 3번 세로 줄의 알람을 모두 끄는 것은 안 됩니다. 여러 번 알람을 끌 때 항상 가로로만 끄거나 세로로만 꺼야 한다는 겁니다. 사실 이러한 조건 때문에 이 문제는 매우 쉬운 단순 구현 문제에요.


  만약에 가로, 세로를 번갈아가면서 선택하며 끌 수 있었다면 이분 매칭(Bipartite Matching) 문제로 분류되어 조금 더 어려워집니다. 하지만 이 문제는 반드시 가로 혹은 세로로만 꺼야 한다는 강력한 제약 조건이 붙어 있으므로 단순히 <가로로만 끌 때의 경우의 수>와 <세로로만 끌 때의 경우의 수> 중에서 더 작은 수를 계산하여 출력하기만 하면 됩니다.


※ 예시 입출력 ※


input

4
1 1
1 2
2 3
3 3

output

3

※ 정답 소스코드 ※

(컴파일 환경: GNU G++11 5.1.0)

#include <iostream>
#include <stdio.h>
#include <limits.h>

using namespace std;

int a[101][101];

int main(void) {
	int n;
	cin >> n;
	for(int i = 0; i < n; i++) {
		int x, y;
		cin >> x >> y;
		a[x][y] = 1;
	}
	int res = INT_MAX;
	int count = 0;
	for(int i = 0; i < 101; i++) {
		for(int j = 0; j < 101; j++) {
			if(a[i][j]) {
				count++;
				break;
			}
		}
	}
	res = min(res, count);
	count = 0;
	for(int i = 0; i < 101; i++) {
		for(int j = 0; j < 101; j++) {
			if(a[j][i]) {
				count++;
				break;
			}
		}
	}
	res = min(res, count);
	cout << res;
	return 0;
}


728x90
반응형

728x90
반응형

문제 유형: 구현

문제 URL: http://codeforces.com/contest/399/problem/A


  이 문제는 구현의 끝판왕 문제인 게시판 페이징(Paging) 문제입니다. 전체 페이지의 개수를 N, 현재 페이지를 P, 현재 페이지를 기준으로 왼쪽과 오른쪽에 몇 개의 페이지까지 표시할 지를 K라고 합니다. 이 때 << 3 4 (5) 6 7 >>와 같은 방식으로 페이징 처리를 하면 됩니다.


  왼쪽으로 페이지가 더 남았을 때는 "<<"를 출력하고, 오른쪽으로 페이지가 더 남았을 때는 ">>"를 출력합니다. 실제 게시판을 구현할 때도 비슷한 방식의 페이징 처리 알고리즘 구현해 본 경험이 있다는 점에서 재미있게 풀 수 있었습니다.


※ 예시 입출력 ※


input

17 5 2

output

<< 3 4 (5) 6 7 >> 

※ 정답 소스코드 ※
(컴파일 환경: GNU G++11 5.1.0)
#include <iostream>
#include <stdio.h>

using namespace std;

int main(void) {
	int n, p, k;
	cin >> n >> p >> k;
	// 왼쪽으로 이동이 가능한 경우 
	if(p - k > 1) {
		cout << "<< ";
	}
	for(int i = ((p - k > 1)? p - k : 1); i < p; i++) {
		cout << i << ' ';
	}
	// 현재 페이지를 출력 
	cout << "(" << p << ") ";
	for(int i = p + 1; i <= ((p + k < n)? p + k : n); i++) {
		cout << i << ' ';
	}
	// 오른쪽으로 이동이 가능한 경우 
	if(p + k < n) {
		cout << ">>";
	}
	return 0;
}


728x90
반응형

728x90
반응형

문제 유형: 수학

문제 URL: http://codeforces.com/contest/393/problem/A


  이 문제는 특정한 문자열이 주어졌을 때 그 문자열의 문자들을 재정렬해서 "nineteen"이라는 문자열을 몇 개나 만들 수 있는지 물어보는 문제입니다. 예를 들어 문자열 "xiineteenppnnnewtnee"이 주어졌을 때 이를 "xnineteenppnineteenw"와 같이 재정렬한다면 "nineteen" 문자열이 두 번 나오게 되는 것입니다. 따라서 위 경우 최대 2개 만들 수 있으므로 정답은 2입니다.


  또한 "nineteen"이라는 문자열의 개수를 셀 때는 전체 문자열을 앞에서부터 한 자씩 읽어 확인하므로 문자를 읽다가 건너 뛸 수 없습니다. 또한 문자 n은 끝과 시작이 이어질 수 있습니다. 예를 들어 "nineteenineteen"과 같이 나열하면 n의 개수가 5개여도 "nineteen"을 2번 찾을 수 있습니다.


  이 문제는 단순히 n, i, e, t 문자의 개수를 세서 풀 수 있습니다. "nineteen"은 n 3개, i 1개, e 3개, t 1개로 이루어집니다. 따라서 만들 수 있는 "nineteen"의 최대 개수를 구하기 위해서는 각 문자를 몇 개씩 가지고 있느냐를 기준으로 개수를 찾을 수 있을 것입니다. 특히 n은 끝과 시작이 이어질 수 있기 때문에 사실상 n은 2개만 있어도 하나의 "nineteen"을 구성할 수 있다고 고려해야 합니다.


※ 정답 소스코드 ※


(컴파일 환경: GNU G++11 5.1.0)

#include <iostream>
#include <stdio.h>
#include <limits.h>

using namespace std;

int main(void) {
	int nC = 0;
	int iC = 0;
	int eC = 0;
	int tC = 0;
	string input;
	cin >> input;
	for(int i = 0; i < input.size(); i++) {
		if(input[i] == 'n') nC++;
		else if(input[i] == 'i') iC++;
		else if(input[i] == 'e') eC++;
		else if(input[i] == 't') tC++;
	}
	int res = INT_MAX;
	if(nC > 3) {
		// n은 끝과 시작이 이어질 수 있습니다. 
		res = min(res, (nC - 1) / 2);
	}
	else {
		res = min(res, nC / 3);
	}
	res = min(res, iC);
	res = min(res, tC);
	res = min(res, eC / 3);
	cout << res;
	return 0;
}


728x90
반응형