A. Pretty Permutations
https://codeforces.com/contest/1541/problem/A
Problem - A - Codeforces
codeforces.com
1부터 n까지 숫자들은 자기자신에 해당하는 인덱스에 있지 않은 상태 && 각 숫자별 움직이는 횟수 합이 가장 작게 하여 정렬시킬 수 있는 경우를 출력해야한다.
나같은 경우 n개의 숫자를 n번 움직여서 정렬시키는 문제로 잘못 읽어서 시간을 좀 써버렸다. 아니었으면 세자리 등수 안에 들어갔을 수도..
각설하고 최적의 상태는
내가 생각한 최적은 짝수일 때
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 2147483647;
ll gcd(ll a, ll b) { for (; b; a %= b, swap(a, b)); return a; }
int a[101];
int main() {
ios::ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
for (int i = 0; i < 101; i += 2) a[i] = i + 2;
for (int i = 1; i < 101; i += 2) a[i] = i;
int T;
cin >> T;
while(T--){
int n;
cin >> n;
if (n % 2 == 0) {
for (int i = 0; i < n; i++) cout << a[i] << ' ';
}
else {
for (int i = 0; i < n - 3; i++) cout << a[i] << ' ';
cout << n << ' ';
for (int i = n - 2; i < n; i++) cout << i << ' ';
}
cout << '\n';
}
return 0;
}
B. Pleasant Pairs
https://codeforces.com/contest/1541/problem/B
Problem - B - Codeforces
codeforces.com
완전탐색을 하는데 시간을 줄일 방법을 생각해야했다.
이제
따라서
결국,
이제 시간 복잡도를 생각해보자.
마지막으로 조화 급수를 이용하면
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 2147483647;
ll gcd(ll a, ll b) { for (; b; a %= b, swap(a, b)); return a; }
int a[100001] = { 0, };
int main() {
ios::ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int T;
cin >> T;
while(T--){
int n;
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
ll ans = 0;
for (int i = 1; i <= n; i++) {
int x = (2 * i) / a[i] + 1; // 올림
int start = x * a[i] - i;
for (int j = start; j <= n; j += a[i]) {
if (a[j] == (i + j) / a[i]) ans++;
}
}
cout << ans << '\n';
}
return 0;
}
C. Great Graphs
https://codeforces.com/contest/1541/problem/C
Problem - C - Codeforces
codeforces.com
입력받은 배열 d를 우선 오름차순으로 정렬시키고 1번부터 n번 목초지가 있다고 생각해보자.
낮은 번호에서 높은 번호로 가는 도로는 많이 지을수록 total weight cost를 낮추는 데에 도움이 안된다. 반대로 높은 번호에서 낮은 번호로 가는 도로는 많이 지을수록 total weight cost가 낮아지기 때문에 최대한 많이 지어야 한다.
정리해보면 낮은 번호 -> 높은 번호 도로는 1->n 으로 가는 도로 하나만 짓고, 높은 번호 -> 낮은 번호 도로는 모두 다 지어야 한다.
B번 문제와 마찬가지로 이중 for문으로 완전탐색을 실시하면
아! 찾았다. 구간 합을 이용하면
구간 합을 통해 답을 구하는 것이기 때문에 시간 복잡도는
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 2147483647;
ll gcd(ll a, ll b) { for (; b; a %= b, swap(a, b)); return a; }
ll d[100001] = { 0, };
ll sum[100001] = { 0, };
int main() {
ios::ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int T;
cin >> T;
while(T--){
int n;
cin >> n;
for (int i = 1; i <= n; i++) cin >> d[i];
sort(d + 1, d + n + 1);
for (int i = 1; i <= n; i++) sum[i] = sum[i - 1] + d[i]; // 구간 합
ll ans = d[n]; // 1 -> n번으로 가는 도로 weight
for (int i = n; i > 1; i--) {
ans += (sum[i - 1]) - (i - 1) * d[i];
}
cout << ans << '\n';
}
return 0;
}
'codeforce' 카테고리의 다른 글
Round #731 (Div. 3) (0) | 2021.07.11 |
---|---|
Round #727 (0) | 2021.06.25 |
Round #725 (Div. 3) (0) | 2021.06.14 |
Round #707 (Div. 2) (0) | 2021.05.25 |
Round #706 (Div. 2) (0) | 2021.05.24 |