Codeforces 1082B: http://codeforces.com/contest/1082/problem/B
題意:
給你一個串,只包含S和G這兩個字符,讓你最多交換一次 S和G的位置,使得連續的G的長度達到最長,打印這個最大長度。
思路:
記兩個vector,分別存每個 S 前面有幾個連續的 G,後面有幾個連讀的 G,然後用max維護一下,這兩個值的和的最大值,有一點需要注意,那就是,如果,當前找到的這個S,前後的連續G加起來,就是總的G的個數,那麼你這個S只能和這裏面開頭或者結尾的G交換才能達到最大,即當前維護到的這個max值就是答案,否則,就意味着,你當前枚舉到的這個S,可以和一個其他的G進行交換,這裏的 “其他的”,指的除去當前S左右兩端的連續G以外的G,所以此時維護到的max還要加上S交換過來的G,即max + 1 纔是最後結果。
我的AC代碼:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxx = 1e5 + 7;
const int Mod = 4e3 + 1;
const int Inf = 1 << 30;
const ll INF = 1ll << 60;
#define mst(x) memset(x, 0, sizeof(x))
map <int, int> mp;
set <int> sst;
typedef pair <int, int> PR;
priority_queue <PR> qua;
int n;
char s[maxx];
vector <int> vecFr;
vector <int> vecBk;
vector <int> vec;
void Init() {
scanf("%d", &n);
scanf("%s", s + 1);
}
int main() {
Init();
int fr = 0;
int cnt = 0;
for(int i = 1; i <= n; i++) {
if(s[i] == 'S') {
cnt++;
vecFr.push_back(fr);
fr = 0;
}
else fr++;
}
int bk = 0;
for(int i = n; i >= 1; i--) {
if(s[i] == 'S') {
vec.push_back(bk);
bk = 0;
}
else bk++;
}
int sz = vec.size();
for(int i = sz - 1; i >= 0; i--) vecBk.push_back(vec[i]);
/*for(int i = 0; i < sz; i++)
cout << vecFr[i] << ' ' << vecBk[i] << endl;*/
int ans = 0;
for(int i = 0; i < sz; i++) {
ans = max(ans, vecFr[i] + vecBk[i]);
}
for(int i = 0; i < sz; i++) {
if(vecFr[i] + vecBk[i] == ans) {
if(vecFr[i] + vecBk[i] < n - cnt) ans++;
break;
}
}
if(!cnt) cout << n << endl;
else cout << ans << endl;
}
Codeforces 1088C: http://codeforces.com/problemset/problem/1088/C
題意:
給你一個長度爲 n (n <= 2000) 的序列 a (a[i] <= 1e5),你只能進行如下兩種操作:
1) 將前綴 k 全部加x
2) 將前綴 k 全部模x
最多進行 n + 1 次,使得這個序列嚴格遞增。
打印操作步數和具體操作。
思路:
既然他都說了,最多進行n + 1步,那我就進行n + 1步,首先我要讓這個序列嚴格遞增,我就最後讓這個序列的值,全變成他的角標,即1 2 3 4 ...。那麼我就首先給這個序列的每個數都加上一個相對大的書Mod,那我怎麼確定這個 Mod 值呢,首先我要想讓 a[i] 都變成他的角標 i,那我就讓 a[i] 每次進行操作2,模的是 (a[i] - i),但是如果我當前 a[i] 裏有多於一個 (a[i] - i),那麼我這個餘數值就不準確了,因此,我需要滿足以下兩個條件
a[i] % (a[i] - i) = i
a[i] / (a[i] - i) = 1
所以我只需要讓 a[i] / (a[i] - i) < 2,即 a[i] > 2i,即可,那麼我 i 的取值就是n的取值範圍,最大是2e3,而我當前 a[i] 就是 a[i] + Mod,由於 0 <= a[i] <= 1e5,因此我的Mod值取一個4e3 + 1(取4e3不行,因爲a[i] = 0時,a[i] + Mod 不一定能保證大於2 * i),就能滿足上述情況了,所以,我直接進行 n + 1步,第一步,給前綴 n 全加上Mod,然後每次讓前綴模 (a[i] - i) 就能滿足嚴格遞增了。
我的AC代碼:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxx = 1e5 + 7;
const int Mod = 4e3 + 1;
const int Inf = 1 << 30;
const ll INF = 1ll << 60;
#define mst(x) memset(x, 0, sizeof(x))
typedef pair <int, int> PR;
priority_queue <PR> qua;
vector <int> vec;
set <int> sst;
map <int, int> mp;
int n;
int a[maxx];
void Init() {
mst(a);
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> a[i];
a[i] += Mod;
}
}
int main() {
Init();
cout << n + 1 << endl;
printf("1 %d %d\n", n, Mod);
for(int i = 1; i <= n; i++) {
int dd = a[i] - i;
printf("2 %d %d\n", i, dd);
}
}