Educational Codeforces Round 96 A-E 題解
https://codeforces.com/contest/1430
A - Number of Apartments
沒有仔細思考,直接暴力寫了。
列舉5個、7個窗戶房子的個數,最多總迴圈次數1e7
#include<bits/stdc++.h>
using namespace std;
int main(){
int t = 0;
cin>>t;
while(t--){
int n;
scanf("%d", &n);
int i = 0, j = 0, k = 0;
bool ok = false;
for(;i*7 <= n; i++){
int x = i * 7;
for(j=0;x + j * 5 <= n; j++){
if((n - i * 7 - j * 5)%3 == 0){
ok = true;
printf("%d %d %d\n", (n - i * 7 - j * 5) / 3, j, i);
break;
}
}
if(ok)break;
}
if(!ok)puts("-1");
}
}
B - Barrels
最優方法是取水前k+1 ~ 2多的桶,全部倒到最多的桶中
#include<bits/stdc++.h>
using namespace std;
const int maxn = 300000;
int a[maxn];
typedef long long LL;
int main(){
int t = 0;
cin>>t;
while(t--){
int n, k;
scanf("%d%d", &n, &k);
for(int i = 0; i < n; i++)
scanf("%d", a+i);
sort(a, a+n);
LL ans = 0;int j = 0;
for(int i = n-2; i >= 0 && j < k; i--)ans += a[i], j++;
ans += a[n-1];
cout<<ans<<endl;
}
}
C - Numbers on Whiteboard
每次操作時考慮最優化全部數的均值,到最後一次時是最優的。因此每次取最大的兩個數,計算平均值向上取整,放回黑板。可以用優先佇列維護。
若是選取奇數,向上取整後代價不會超過選取更小的數,因此不影響結果。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 300000;
typedef long long LL;
int main(){
int t = 0;
cin>>t;
while(t--){
int n;
scanf("%d", &n);
int ans;
priority_queue<int>que;
vector<pair<int, int> > op;
for(int i = 0; i < n; i++)que.push(i+1);
for(int i = 0; i < n-1; i++){
int x = que.top();
que.pop();
int y = que.top();
que.pop();
que.push((x+y+1)/2);
op.push_back({x, y});
}
printf("%d\n", que.top());
for(int i = 0; i < n-1; i++)
printf("%d %d\n", op[i].first, op[i].second);
}
}
D - String Deletion
模擬+貪心。注意到如果第一步操作刪除連續多個序列中的一個,不會使第二步操作的次數減少。第一步操作每次刪除當前位置後第一個連續序列的字元即可。如果不存在,則刪除首字元。需要預處理下一個連續字元的位置。
實現的有點冗餘。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 300000;
typedef long long LL;
int nxt[maxn];
int jump[maxn];
int main(){
int t = 0;
cin>>t;
while(t--){
int n;
scanf("%d", &n);
string s;
cin>>s;
int con = 0;
char pre = s[0];
int j = 0;
for(int i = 0; i < n+10; i++){
nxt[i] = -1;
jump[i] = 0;
}
for(int i = 1; i < n; i++){
if(s[i] == pre){
while(j <= i-1)nxt[j++] = i-1;
}
pre = s[i];
}
int ans = 0;
j = 0;
for(int i = 0; i < n;){
ans++;
while(jump[i]) i++;
if(i >= n)break;
j = max(j, i);
if(nxt[j] != -1){
if(i == nxt[j])i++;
else {
jump[nxt[j]] = 1;
j++;
if(nxt[j] != -1)
while(jump[nxt[j]])j++;
}
while(jump[i]) i++;
pre = s[i];
i++;
while(jump[i]) i++;
while(i < n && s[i] == pre ){
i++;
while(jump[i]) i++;
}
}
else{
i++;
while(jump[i]) i++;
pre = s[i];
i++;
while(jump[i]) i++;
while(i < n && s[i] == pre ){
i++;
while(jump[i]) i++;
}
}
if(i >= n)break;
}
cout<<ans<<endl;
}
}
E - String Reversal
置換數=逆序對數。為翻轉前每個字元編號,相鄰相同字元編號相同,表示可以任意對換位置。否則後字元=前字元編號+1。
翻轉後所有編號反序。為了儘量減少逆序對數量,相同字元內編號可再次反序。最後得到的編號求逆序對數即可。
逆序對數用了模板。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 250000;
typedef long long LL;
int pp[26][maxn];
int cnt[26] = {};
int a[maxn];int tmpA[maxn];
LL ans = 0;
void merge_sort(int l, int r, int *A) {
if (l >= r) return ;
int mid = (l + r) >> 1;
merge_sort(l, mid, A);
merge_sort(mid + 1, r, A);
int pl = l, pr = mid + 1, tmpp = 0;
while(pl <= mid && pr <= r) {
if (A[pl] <= A[pr]) tmpA[tmpp++] = A[pl++];
else tmpA[tmpp++] = A[pr++], ans += mid - pl + 1;
}
while(pl <= mid) tmpA[tmpp++] = A[pl++];
while(pr <= r) tmpA[tmpp++] = A[pr++];
for (int i = 0; i < tmpp; i++) A[i + l] = tmpA[i];
}
int main(){
int n;
scanf("%d", &n);
string s;
cin>>s;
for(int i = 0; i < n; i++)s[i] -= 'a';
pp[s[0]][0] = 1;
int pre = s[0];
cnt[s[0]] = 1;
int pos = 1;
for(int i = 1; i < n; i++) {
if(s[i] != pre) pos++;
pp[s[i]][cnt[s[i]]++] = pos;
pre = s[i];
}
for(int i = 0; i < n; i++) {
a[i] = pp[s[i]][--cnt[s[i]]];
a[i] = n + 1 - a[i];
//cout<<a[i]<<endl;
}
merge_sort(0, n-1, a);
cout<<ans<<endl;
}
相關文章
- 【題解】Educational Codeforces Round 82
- Educational Codeforces Round 143 (Rated for Div. 2) A-E
- Codeforces Round 976 (Div. 2) 題解(A-E)
- Codeforces Round 981 (Div. 3) 題解(A-E)
- Educational Codeforces Round 166 個人題解(A~D)
- Educational Codeforces Round 166(A-D題解)
- Educational Codeforces Round 93 (Rated for Div. 2)題解
- Educational Codeforces Round 171 (Rated for Div. 2) 題解
- Educational Codeforces Round 32
- Educational Codeforces Round 168 (Rated for Div. 2) 題解
- Codeforces Educational Round#98 A
- Educational Codeforces Round 1 Tutorial
- Educational Codeforces Round 163
- Educational Codeforces Round 172 Solution
- Educational_round94題解
- Educational Codeforces Round 172 (Rated for Div. 2)題解記錄(A~D)
- Codeforces Round #846 (Div. 2) A-E
- Codeforces Round #851 (Div. 2) A-E
- Educational Codeforces Round 171 (Div. 2)
- codeforces Educational Codeforces Round 33 (Rated for Div. 2)
- [CF1954] Educational Codeforces Round 164 (Rated for Div. 2) 題解
- Educational Codeforces Round 37 (Rated for Div. 2)
- Educational Codeforces Round 93 (Rated for Div. 2)
- Educational Codeforces Round 170 (Rated for Div. 2)
- Educational Codeforces Round 171 div2(A~E)
- Educational Codeforces Round 19 E. Array Queries
- Educational Codeforces Round 172 (Rated for Div. 2)
- codeforces Educational Codeforces Round 33 (Rated for Div. 2)B
- Educational Codeforces Round 163 (Rated for Div. 2) 補題記錄(A~A)
- Educational Codeforces Round 100-C. Busy Robot
- Educational Codeforces Round 100 (Rated for Div. 2)
- Educational Codeforces Round 33 (Rated for Div. 2) C
- Educational Codeforces Round 34 (Rated for Div. 2) D
- Educational Codeforces Round 163 (Rated for Div. 2)
- Educational Codeforces Round 154 (Rated for Div. 2)
- Educational Codeforces Round 168 (Rated for Div. 2)
- 2024.12.2 Educational Codeforces Round 172
- Educational Codeforces Round 165 (Rated for Div. 2) C. Minimizing the Sum題解