problem A 加训时间!

根据题意可知,答案为数组最大值

problem B 爆wa种子!

对于形如的函数方程只可能有三种情况:

  1. 抛物线,由于数据保证,所以必定开口向上,那么此时最低点坐标可以由得到再代入方程即可得到最小值
  2. 一条平行于轴的直线
  3. 一条既不平行于轴也不平行于轴的直线

如果出现情况3,答案只能是负无穷。

如果没出现过情况3,则对情况1以及情况2求出的最低点取即可。

problem C 晚上不睡觉

输出的错误答案即可。例如可以直接输出

problem D 书生的负数

当将所有数字相加,数字之和大于时将除最后一个数之外的所有数改为,最后一个数为非负数,输出; 否则所有的数都可以改为负数,输出

problem E 明天

的子串全部提取出来,存到map中,每次判断即可。

#include <bits/stdc++.h>
using namespace std ;
 
int main()
{
	ios::sync_with_stdio(false) ;
	cin.tie(nullptr) ;
 
	map<string, bool> mp ;
	string T = "tomorrow" ;
 
	for(int i = 0; i < 8; ++ i)
		for(int j = i; j < (!i ? 7 : 8); ++ j)
			mp[T.substr(i, j - i + 1)] = 1 ;
 
	int Q ; cin >> Q ;
	while(Q --)
	{
		string s ; cin >> s ;
		cout << (mp.count(s) ? "yes" : "no") << '\n' ;
	}
	return 0 ;
}

problem F 跳棋

观察到如果有任意两个棋子相邻,整个棋盘的位置都能被跳到,枚举一下判断是否有棋子相邻即可。

#include <bits/stdc++.h>
using namespace std ;
using ll = long long ;
 
int main()
{
	ios::sync_with_stdio(false) ;
	cin.tie(nullptr) ;
 
	int n ; string s ; cin >> n >> s ;
	for(int i = 0; i < n - 1; ++ i)
		if(s[i] == 'X' && s[i + 1] == 'X')
			return cout << n << '\n', 0 ;
 
	int ans = 0 ;
	for(int i = 0; i < n; ++ i) ans += s[i] == 'X' ;
	cout << ans << '\n' ;
	return 0 ;
}

problem G 河流管理

并查集。

每一次打开挡板,便将当前的河段与下一段河流合并,然后跳到下一段尚未与当前河段合并的河流继续合并。

#include <bits/stdc++.h>
using namespace std ;
const int N = 5e5 + 5 ;

int n, q ;
int a[N], fa[N], nxt[N] ;

int get(int x) { return x == fa[x] ? x : fa[x] = get(fa[x]) ; }

int main()
{
    ios::sync_with_stdio(false) ;
    cin.tie(nullptr) ;

    cin >> n >> q ;
    for(int i = 1; i <= n; ++ i) cin >> a[i] ;

    for(int i = 1; i <= n; ++ i) fa[i] = i, nxt[i] = i + 1 ;

    while(q --)
    {
        int opt ; cin >> opt ;
        if(opt == 1)
        {
            int l, r, g ; cin >> l >> r ;
            while((g = nxt[get(l)]) <= r)
            {
                int fl = get(l), fr = get(g) ;
                fa[fl] = fr ;
                a[fr] =  max(a[fr], a[fl]) ;
                l = g ;
            }
        }
        else
        {
            int x ; cin >> x ;
            cout << a[get(x)] << '\n' ;
        }
    }
    return 0 ;
}

problem H 冒险

观察到背包内物品体积成指数级增长,所以背包内物品个数在级别。

假设背包内要放入个物品,显然那么一定是放入前小的物品,且优先放体积较小的物品。

排序后暴力枚举选多少个物品即可。

#include <bits/stdc++.h>
using namespace std ;
#define ll long long
const int N = 1e6 + 5, M = 20 ;
const ll INF = 1e18 ;
int n, k, a[N] ;
ll f[M] ;
int main()
{
    ios::sync_with_stdio(false) ;
    cin >> n >> k ;
    for(int i = 1; i <= n; ++ i) cin >> a[i] ;
    sort(a + 1, a + n + 1) ;
    int ans = 0 ;
    for(int i = 0; i <= min(M - 1, n); ++ i)
    {
        ll t = 0 ;
        for(int j = 1; j <= i; ++ j)
            t += a[j] * (1ll << (i - j)) ;
        if(t <= k) ans = i ;
    }
    cout << ans << '\n' ;
    return 0 ;
}

problem I 妙wa种子!

由于每段对于答案的贡献是该段中的最大值,那么最优方案就是选出这些数中前大的数求和。

我们先选出前大的数,以这些前大的数为起点不断往左、右扩张,直到这些前个数所在段能覆盖整个数组,就划分出了每段。

problem J 货币系统

由裴蜀定理可得能凑出的最小正整数为,所以判断是否为即可。

problem K 从南到北II

读入字符串,从逐个比对,每一位和后面两位是否是“”和“”,如果为“”和“”则将这三位改为,最后输出非的字符即可。

problem L 选拔

找到每个数组的最大值,然后把剩下的放进一个数组里。由于之前已经选了个数组的最大值,所以还需选出个,将数组按降序排序后选出前个即可。

problem M 远方

如果所有的建筑物都不会挡住enterdawn的视线,即时,输出,否则输出

#include <bits/stdc++.h>
using namespace std ;
 
int main()
{
	ios::sync_with_stdio(false) ;
	cin.tie(nullptr) ;
 
	int n, x, y, maxv = -1 ; cin >> n >> x ;
	for(int i = 1; i <= n; ++ i)
	{
		cin >> y ;
		maxv = max(maxv, y) ;
	}
 
	cout << (x > maxv ? "yes" : "no") << '\n' ;
	return 0 ;
}