这是好的

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

注意到模数不大,将00M1M-1个数字看作一个点,对于ii,将它与i+b(modM)i+b\pmod M连一条单向边,显然每个点出度为1,入度也为11,因此,无论从哪个点出发,在MM步以内,一定会走到一个环上,之后的路就没必要走了。

所以我们暴力处理等差数列的前MM项的最大值即可。

#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

做法很多,介绍两种。

O(nlogn)O(n\log n)做法

对于每个数,考虑选择前面一个比他小的最大的数,也就是前驱,可以用平衡树或者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;
}

O(n)O(n)做法

对于每个数,考虑在后面选一个最大的数,维护一个后缀最大值即可。

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