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