这是好的
T1
自己数数,没有35。
#include <bits/stdc++.h>
using namespace std;
int main()
{
cout << 35;
}
T2
总金额可以直接将总盘数乘10,吃的最多的菜可以直接找最大值对应的字符串。
#include <bits/stdc++.h>
using namespace std;
long long n, x, mx, sum;
string mxs, s;
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> s >> x;
sum += x;
if (x > mx) {
mx = x;
mxs = s;
}
}
cout << 10 * sum << endl << mxs << endl;
}
T3
注意到模数不大,将至个数字看作一个点,对于,将它与连一条单向边,显然每个点出度为1,入度也为,因此,无论从哪个点出发,在步以内,一定会走到一个环上,之后的路就没必要走了。
所以我们暴力处理等差数列的前项的最大值即可。
#include <bits/stdc++.h>
using namespace std;
long long a, b, m, vis[1000005], mx;
int main() {
cin >> a >> b >> m;
while (vis[a] == 0) {
vis[a] = 1;
a += b;
a %= m;
mx = max(a, mx);
}
printf("%lld", mx);
}
T4
对于每个字符串直接判断即可,因为有空格,可以使用getline
读入,或者使用getchar
一个一个字符读入。
#include <bits/stdc++.h>
using namespace std;
long long n, ans;
string s;
int main() {
cin >> n;
n++;
while (n--) {
getline(cin, s);
if (s[0] == 'y' && s[1] == 'e' && s[2] == 's') {
if (s[3] == ',' || s[3] == '.' || s[3] == ' ') {
ans++;
}
}
if (s[0] == 'n' && s[1] == 'o') {
if (s[2] == ',' || s[2] == '.' || s[2] == ' ') {
ans++;
}
}
}
cout << ans << endl;
return 0;
}
T5
其实和采药那道题一模一样,包括数据。
T6
做法很多,介绍两种。
做法
对于每个数,考虑选择前面一个比他小的最大的数,也就是前驱,可以用平衡树或者set
维护。
FHQ Treap代码
#include <bits/stdc++.h>
using namespace std;
long long n, op, x, tot, rt, rt1, rt2, sum = -1;
struct node {
long long l, r, val, pri, sz;
} t[1000005];
void pushup(long long rt) {
if (rt) {
t[rt].sz = t[t[rt].l].sz + t[t[rt].r].sz + 1;
}
}
void split(long long rt, long long &lrt, long long &rrt, long long x) {
if (rt == 0)
lrt = 0, rrt = 0;
else if (t[rt].val <= x)
lrt = rt, split(t[rt].r, t[rt].r, rrt, x);
else
rrt = rt, split(t[rt].l, lrt, t[rt].l, x);
pushup(rt);
}
void merge(long long &rt, long long lrt, long long rrt) {
if (lrt == 0 || rrt == 0)
rt = lrt + rrt;
else if (t[lrt].pri < t[rrt].pri)
rt = lrt, merge(t[rt].r, t[rt].r, rrt);
else
rt = rrt, merge(t[rt].l, lrt, t[rt].l);
pushup(rt);
}
void ins(long long &rt, long long x) {
split(rt, rt1, rt2, x);
t[++tot].val = x, t[tot].pri = rand(), t[tot].sz = 1;
merge(rt1, rt1, tot), merge(rt, rt1, rt2);
}
long long kth(long long &rt, long long x) {
// cout<<rt<<' '<<t[rt].val<<' '<<t[rt].h<<' '<<t[rt].sz<<endl;
if (rt == 0)
return 1e9;
if (x <= t[t[rt].l].sz)
return kth(t[rt].l, x);
if (x == t[t[rt].l].sz + 1)
return t[rt].val;
return kth(t[rt].r, x - t[t[rt].l].sz - 1);
}
long long rk(long long &rt, long long x) {
if (rt == 0)
return 1;
if (x <= t[rt].val)
return rk(t[rt].l, x);
return rk(t[rt].r, x) + t[t[rt].l].sz + 1;
}
int main() {
scanf("%lld", &n);
while (n--) {
scanf("%lld", &x);
long long pr = kth(rt, rk(rt, x) - 1);
if (pr == 1000000000)
pr = -pr;
sum = max(sum, x + pr);
ins(rt, x);
}
printf("%lld", sum);
}
set做法
#include <bits/stdc++.h>
using namespace std;
set<long long> s;
long long n, a[100005], mx;
int main() {
s.clear();
mx = -1;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
s.insert(a[i]);
auto y = s.lower_bound(a[i]);
if (y != s.begin()) {
mx = max(mx, a[i] + *(--y));
}
}
cout << mx << endl;
}
做法
对于每个数,考虑在后面选一个最大的数,维护一个后缀最大值即可。
#include <bits/stdc++.h>
#include<bits/extc++.h>
using namespace std;
int n,a[100001],f[100001],ans=-1;
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
for(int i=n-1;i>=1;i--){
f[i] = max(f[i+1],a[i]);
if(a[i-1]<f[i]) ans = max(ans,a[i-1]+f[i]);
}
printf("%d",ans);
return 0;
}