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);
}
}