티스토리 뷰
이 그룹 에서 매일 문제를 푼다.
| 오늘의 문제 |
무슨 내용을 넣어야 좋을까요?
www.acmicpc.net
18108번: 1998년생인 내가 태국에서는 2541년생?!
ICPC Bangkok Regional에 참가하기 위해 수완나품 국제공항에 막 도착한 팀 레드시프트 일행은 눈을 믿을 수 없었다. 공항의 대형 스크린에 올해가 2562년이라고 적혀 있던 것이었다. 불교 국가인 태국�
www.acmicpc.net
푸실 수 있죠?
2167번: 2차원 배열의 합
첫째 줄에 배열의 크기 N, M(1 ≤ N, M ≤ 300)이 주어진다. 다음 N개의 줄에는 M개의 정수로 배열이 주어진다. 배열에 포함되어 있는 수는 절댓값이 10,000보다 작거나 같은 정수이다. 그 다음 줄에는 �
www.acmicpc.net
브루트 포스
10972번: 다음 순열
첫째 줄에 입력으로 주어진 순열의 다음에 오는 순열을 출력한다. 만약, 사전순으로 마지막에 오는 순열인 경우에는 -1을 출력한다.
www.acmicpc.net
next_permutation(a,a+n)
끝.
10973번: 이전 순열
첫째 줄에 입력으로 주어진 순열의 이전에 오는 순열을 출력한다. 만약, 사전순으로 가장 처음에 오는 순열인 경우에는 -1을 출력한다.
www.acmicpc.net
prev_permutation(a,a+n)
끝.
10974번: 모든 순열
N이 주어졌을 때, 1부터 N까지의 수로 이루어진 순열을 사전순으로 출력하는 프로그램을 작성하시오.
www.acmicpc.net
do {
print(a)
} while(next_permutation(a,a+n));
끝.
2467번: 용액
첫째 줄에는 전체 용액의 수 N이 입력된다. N은 2 이상 100,000 이하의 정수이다. 둘째 줄에는 용액의 특성값을 나타내는 N개의 정수가 빈칸을 사이에 두고 오름차순으로 입력되며, 이 수들은 모두 -
www.acmicpc.net
알고리즘 : 투 포인터
오름차순 정렬 후 포인터를 \(l\), \(r\) 두개를 잡아서 \(l\)은 \(1\), \(r\)은 \(n\)으로 둔다.
\(a[l]+a[r] < 0\) 이라면 \(l\) 한칸 전진
\(a[l]+a[r] \geq 0\) 이라면 \(r\) 한칸 전진 하면서
각 진행 상황에 대해 \(|a[l]+a[r]|\) 최솟값 저장.
\(l \geq r\) 이 되기 전까지 반복.
끝난 후 정답이 되는 \(l\), 정답이 되는 \(r\) 출력
#include <bits/stdc++.h>
using namespace std;
int a[100001];
int abs(int x){return x > 0 ? x : -x;}
int main(){
int n;
scanf("%d", &n);
for (int i = 0;i < n;i++)
{
scanf("%d",&a[i]);
}
sort(a,a+n);
int left = 0,right = n - 1,ans = 2000000001;
int l = 0,r = 0;
while(left < right)
{
int sum = a[left] + a[right];
if(abs(sum) < ans)
{
ans = abs(sum);
l = left;
r = right;
if(ans == 0) break;
}
if(sum < 0) left++;
else right--;
}
printf("%d %d",a[l],a[r]);
}
3114번: 사과와 바나나
문제 A나라와 B나라가 국경선을 놓고 몇 년째 싸우고 있다. 분쟁 지역의 크기는 직사각형이고, R×C 개의 칸으로 나누어져 있다. 모든 칸에는 사과 나무 또는 바나나 나무가 심어져 있다. 방금, 기�
www.acmicpc.net
알고리즘 : 동적 계획법
\(DP[i][j]\) : 불도저가 \(i\)번째 열 \(j\)번째 행 지점에 있을때 가능한 최대 조건을 충족하는 과일 수.
라고 두면
\(DP[i][j] = max(DP[i-1][j]+Sum(B[i][1]~B[i][j]),DP[i][j-1]+B[i][j]-A[i][j])\) 가 됨을 알 수 있다.
16161번: 가장 긴 증가하는 팰린드롬 부분수열
팰린드롬 수열이란 앞에서부터 읽을 때와 뒤에서부터 읽을 때 똑같은 수열을 말한다. 수열 {13, 25, 3, 25, 13}, {9, 5, 5, 9}는 팰린드롬이고, {1, 2, 3, 4, 5, 6, 7, 6}, {1, 2, 5, 4, 2}, {1, 1, 3, 2, 4}는 팰린드��
www.acmicpc.net
헤헤 나도 어떻게 풀지 모른다.
2505번: 두 번 뒤집기
첫줄에는 숫자판의 크기를 나타내는 정수 N (5≤N≤10,000)이 주어진다. 그 다음 줄에는 두 개의 구간이 뒤집혀진 놀이판의 상태를 나타내는 숫자들이 하나의 공백을 두고 나타난다.
www.acmicpc.net
뒤집어야 할 구간을 두개 구해줘야 한다.
일단 왼쪽부터 가면서 자신의 위치랑 원래 있어야 할 숫자가 다른지 본다. ($i$번째 위치라 하자)
다르다면, \(i\)가 배열에 어디있는지 찾는다. 그러면 처음 뒤집을 구간이 정해졌다!
뒤집고 나면, 어딘가 또 안되는 부분이 있을 것이다. 그것도 똑같이 찾아준다.
만약 완성이 되었다면 1~1 구간을 뒤집어 준다. (횟수 날리기)
근데 이렇게 하면 불가능 한 경우가 있다.
그래서 오른쪽 부터 보는 것도 해봐야 한다.
똑같은 방법으로 진행한다.
코드가 조금 드러우니 보지 않는걸 추천한다.
#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair <ll,ll> pl;
typedef pair <int,int> pi;
int n;
int a[10005];
int st,en;
vector <pi> ans;
int main() {
ios_base::sync_with_stdio(false); cin.tie(0);
cin >> n;
for(int i = 1;i <= n;i++) {
cin >> a[i];
}
st = 0;
for(int i = 1;i <= n;i++) {
if(a[i] != i) {
st = i;
for(int j = 1;j <= n;j++) {
if(a[j] == i) {
en = j; break;
}
}
break;
}
}
if(st > en) swap(st,en);
if(!st) st = 1, en = 1, ans.push_back({1,1});
else ans.push_back({st,en});
reverse(a+st,a+en+1);
st = 0;
en = 0;
for(int i = 1;i <= n;i++) {
if(a[i] != i) {
st = i;
for(int j = 1;j <= n;j++) {
if(a[j] == i) {
en = j; break;
}
}
break;
}
}
if(st > en) swap(st,en);
if(!st) st = 1, en = 1, ans.push_back({1,1});
else ans.push_back({st,en});
reverse(a+st,a+en+1);
int c = 0;
for(int i = 1;i <= n;i++) {
if(a[i] != i) {
c = 1;
break;
}
}
if(!c) {
cout << ans[0].x << ' ' << ans[0].y << '\n' << ans[1].x << ' ' << ans[1].y << '\n';
return 0;
}
reverse(a+ans[1].x,a+ans[1].y+1);
reverse(a+ans[0].x,a+ans[0].y+1);
ans.clear();
st = 0;
for(int i = n;i >= 1;i--) {
if(a[i] != i) {
st = i;
for(int j = 1;j <= n;j++) {
if(a[j] == i) {
en = j; break;
}
}
break;
}
}
if(st > en) swap(st,en);
if(!st) st = 1, en = 1, ans.push_back({1,1});
else ans.push_back({st,en});
reverse(a+st,a+en+1);
st = 0;
en = 0;
for(int i = n;i >= 1;i--) {
if(a[i] != i) {
st = i;
for(int j = 1;j <= n;j++) {
if(a[j] == i) {
en = j; break;
}
}
break;
}
}
if(st > en) swap(st,en);
if(!st) st = 1, en = 1, ans.push_back({1,1});
else ans.push_back({st,en});
reverse(a+st,a+en+1);
cout << ans[0].x << ' ' << ans[0].y << '\n' << ans[1].x << ' ' << ans[1].y << '\n';
}
2727번: 2,3 거듭제곱의 합
문제 모든 자연수 N은 (2a)(3b)의 합으로 나타낼 수 있다. 이때, 서로 약수/배수 관계인 두 항이 있어서는 안 된다. 1 = (20)(30) 7 = (22)(30) + (20)(31) 31 = (24)(30) + (20)(32) + (21)(31) = (22)(30) + (20)(33) N이 주어��
www.acmicpc.net
이번 셋에서 내가 제일 좋아하는 문제다.
진짜 하나만 생각하면 풀리는 것이다.
우린 3을 사용하지 않는다. 정확히 말하면 3의 지수는 모두 0으로 사용할 것이다.
그러면... 우린 2의 제곱수만을 가지고 어떤 수 $x$를 만들라는 문제가 된다.
$x$를 이진 수로 표현해보면 나타나는 1의 위치를 출력하면 된다.
문제를 제대로 읽지 않고 풀었지만, 스페셜 저지가 이상해 맞은것으로 처리되었습니다.
현재는 정상적으로 수정되었고 위의 풀이는 틀린 풀이입니다.
#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair <ll,ll> pl;
typedef pair <int,int> pi;
ll x,T;
vector <ll> ans;
int main() {
ios_base::sync_with_stdio(false); cin.tie(0);
cin >> T;
while(T--) {
ll n; cin >> n; ans.clear();
x = 0;
while(n) {
if(n%2) ans.push_back(x);
x++; n /= 2;
}
cout << ans.size() << '\n';
for(ll i : ans) cout << i << " 0\n";
}
}
2561번: 세 번 뒤집기
첫 세 줄에 뒤집어야 할 각 구간을 차례대로 출력해야 한다. 각 줄에는 구간[i, j]를 나타내는 i와 j를 빈 칸을 사이에 두고 출력해야 한다. 입력에 대한 답은 항상 존재한다.
www.acmicpc.net
능지가 딸려서 못풀었다.
- Total
- Today
- Yesterday
- BOJ
- hyper
- ABC
- 수열과 쿼리
- 하이퍼
- 쿼리
- 알고리즘 문제 풀이
- Rabin-Karp
- 냄새 싫어
- 오일러 경로
- 세그먼트 트리
- 정렬
- AtCoder
- 간단한 풀이
- Constructive
- combination
- 스택
- gunwookim
- 김춘배
- 누적 합
- codeforces
- 앳코더
- Offline Dynamic Connectivity
- 1909
- 비요뜨 존맛
- DP
- PS
- 비요뜨
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |