A

题面:输入一个大小为n的数组,可以将数组中任意一个数变成数组中除了它本身的任意一个数,问你是否能将数组之和变成奇数?

solution:如果本来就是奇数直接输出yes,否则遍历数组,如果全部都是奇数或者全部都是偶数则输出no,否则输出yes

std:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 2005;
int a[maxn];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        int sum = 0,cnt1 = 0,cnt2 = 0;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            sum += a[i];
        }
        if(sum%2){
            printf("YES\n");
            continue ;
        }
        for(int i=1;i<=n;i++)
        {
            if(a[i]%2!=0){
                cnt1++;
            }else{
                cnt2++;
            }
        }
        if(cnt1 == 0 || cnt2 == 0){
            printf("NO\n");
            continue ;
        }
        printf("YES\n");
    }
    return 0;
}

B

题面:输入数字n,代表你有n元钱,当你花费k元能获得floor(k/10)元,即向下取整,问你一共消费的最大金额?

solution:一直对10取模往下除,记得加上对10取模的数

std:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,ans = 0;
        cin>>n;
        while(n>=10)
        {
            int x = n/10;
            int y = n%10;
            ans += (x*10);
            n = x + y;
        }
        ans += n;
        cout<<ans<<endl;
    }
    return 0;
}

C

题面:给出一个长度为n的字符串,代表机器人在二维平面上的走法,UDLR分别代表上下左右,问你能否选取一段最短的子串(连续),该子串是一段从起点又回到起点的路径,如果没有输出-1?

solution:map< pair , int > 记录二维坐标的位置,如果到达之前到达的点,更新最小值答案,更新该点的map

std:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
string s;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        cin>>s;
        int x = 0,y = 0;
        map< pair<int , int> , int > mp;
        int l = -1,r = n;
        mp[{x,y}] = 0;
        for(int i=0;i<n;i++)
        {
            if(s[i] == 'L'){ y--;}
            if(s[i] == 'R'){ y++;}
            if(s[i] == 'U'){ x++;}
            if(s[i] == 'D'){ x--;}
            if(mp.count({x,y}))
            {
                if(i - mp[{x,y}] + 1 < r - l + 1){
                    l = mp[{x,y}];
                    r = i;
                }
            }
            mp[{x,y}] = i+1;
        }
        if(l == -1){
            cout<<"-1"<<endl;
            continue ;
        }
        cout<<l+1<<" "<<r+1<<endl;
    }
    return 0;
}

D

题面:给出n个怪物和怪物的血量ai,自己的攻击力a,敌人的攻击力b,以及自己的超能力k,当攻击一个怪物的时候,自己先手,敌人后手,我将怪物杀死,我得1分,敌人将怪物杀死,我不得分,然后开始下一个怪物,我的超能力一共有k次,代表我最多可以有k次机会中断敌人的攻击,问我能获得的最高得分?

solution:题目看起来很麻烦,只需将ai%(a+b),这里注意!如果等于0,ai = a+b,然后将aisort一遍,如果小于等于a,就不需要超能力,否则,需要超能力,遍历到k<需要的超能力暂停,输出答案即可

std:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 200005;
ll h[maxn],c[maxn];
int main()
{
    ll n,a,b,k;
    int ans = 0,cnt = 0;
    cin>>n>>a>>b>>k;
    for(int i=1;i<=n;i++)
    {
        cin>>h[i];
        h[i] = h[i]%(a + b);
        if(h[i] == 0){
            h[i] = a+b;
        }
    }
    sort(h+1,h+1+n);
    for(int i=1;i<=n;i++)
    {
        if(h[i] <= a){
            ans++;
            continue ;
        }
        if(h[i] % a == 0){
            h[i] = (h[i]/a) - 1;
        }else{
            h[i] = h[i]/a;
        }
        if(h[i] <= k){
            k -= h[i];
            ans++;
        }else{
            break ;
        }
    }
    cout<<ans<<endl;
    return 0;
}

E1和E2

题面:题目给出一个长度为n全部由小写字母组成的字符串,让你给每一个字母涂上颜色,使得将这些字母可以按照”相邻字母颜色不同的方法调换排序,使得字符串最后成为一个非递减的字符串“,输出最少使用的颜色个数,输出每一个字母的颜色,spj

solution:挺好的一道题,其实这一题考的就是最少的非递减子序列的个数,没那么复杂,你只需要O(n*26暴力求出来每一个字母的颜色即可)

std:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 200005;
int ans[maxn],pos[30];
string s;
int main()
{
    int n,maxx = 0;
    cin>>n;
    cin>>s;
    for(int i=0;i<n;i++)
    {
        for(int j=1;j<=26;j++)
        {
            if(s[i] >= pos[j]){
                pos[j] = s[i];
                ans[i] = j;
                maxx = max(maxx , j);
                break ;
            }
        }
    }
    cout<<maxx<<endl;
    for(int i=0;i<n;i++)
    {
        if(i != 0)
            cout<<" ";
        cout<<ans[i];
    }
    return  0;
}