21-22(2)第0次线上赛
*或许我的做法不是最简单的
一、逆序-2
描述
给你一个数组 a,下标为 1 到 n,你需要按顺序执行以下操作:
1、把所有数字加上它的下标,即 a[i] += i
2、把所有数字的顺序颠倒,例如 123 变为 321,100 变成 1(前面的零要去掉)
3、逆向输出数组,即输出 a[n]、a[n - 1] … a[1]
输入
只有一组案例,第一行是一个正整数 n 表示数字的数量。(1 <= n <= 100)
然后是 n 个不大于 100 的正整数。
输出
按照题意输出,每两个数字之间用空格隔开,最后一个数字后面没有空格,结尾换行。
样例输入
3
11 23 37
样例输出
4 52 21
code:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int f(int n){//将所有数字的顺序颠倒,例如123变为321,100变成1(前面的零要去掉)
int ans=0;
while(n){
int x=n%10;
ans=ans*10+x;
n/=10;
}
return ans;
}
int main(){
int n;
cin>>n;
int a[n+1];
for(int i=1;i<=n;i++){
cin>>a[i];
a[i]+=i;//吧所有的数字加上他的下标
a[i]=f(a[i]);
}
cout<<a[n];//逆向输出数组
for(int i=n-1;i>=1;i--){
cout<<" "<<a[i];
}
cout<<endl;//结尾换行
}
二、签到题-7
描述
给你一个字符串,请你找到其中与众不同的那个字符。
与众不同的字符指:在忽略大小写的前提下,跟其它所有字符都不相同,且其它所有字符都相同。
输入
第一行是一个正整数 T 表示测试案例的数量。(1 <= T <= 100)
每组案例是一个字符串 s,保证 s 仅包含英文字母且长度在 3 - 100 之间。
题目保证你总是可以找到那个与众不同的字符。
输出
针对每组案例,输出与众不同的那个字符的 ASCII 码,然后换行。
样例输入
2
aAba
ABA
样例输出
98
66
code:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
string f(string n)//将字符串所有大写字母转换成小写字母
{
for(int i=0;i<n.size();i++){
n[i]=tolower(n[i]);
}
return n;
}
int main(){
int T;
cin>>T;
while(T--){
string s;
cin>>s;
string ss=f(s);//用一个新的字符串储存转换后的字符串
if(ss[0]!=ss[1])//如果第一个字符和第二个字符不一样那么只需要和第三个比较就能知道哪个是特殊字符
{
if(ss[0]==ss[2])
cout<<(int)s[1]<<endl;
else
cout<<(int)s[0]<<endl;
}
else//如果一样那么就找到不特殊的字符,遍历整个字符串找到那个不相同的字符然后输出ASCII码
{
for(int i=2;i<s.size();i++){
if(ss[i]!=ss[0])
cout<<(int)s[i]<<endl;
}
}
}
}
三、WSAD-2
描述
罗少还在玩那个游戏:用 W S A D 分别控制角色进行 上 下 左 右 移动,我们可以把地图看作一个二维平面,罗少初始站在原点。
但是这一次,他写了一个程序让角色自己移动,程序总会使角色按照 W S A D 的顺序移动,每次移动的步长分别为 w、s、a、d。
罗少想知道,在程序进行 n 次操作后,角色所在位置的坐标分别是多少。
输入
第一行是一个正整数 T 表示测试案例的数量。(1 <= T <= 20000)
每组案例包含 5 个不超过 1e9 的正整数 n、w、s、a、d,含义如描述。
输出
针对每组案例,输出角色最后所在位置的下标,然后换行。
样例输入
2
4 1 2 3 4
3 4 3 2 1
样例输出
1 -1
-2 1
code:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
//由题意可见4组一轮回
//数据1e9很大,一步一步走肯定会超时
int main(){
int T;
cin>>T;
while(T--){
ll n;
cin>>n;
ll w,s,a,d;
cin>>w>>s>>a>>d;
ll x=0,y=0;
ll yy=w-s;
ll xx=d-a;
ll t=n/4;//t储存有多少个轮回
ll r=n%4;//r储存t个轮回之后还剩多少步
y+=t*yy;//加上t个轮回走的步数
x+=t*xx;
for(int i=1;i<=r;i++){//余下的步数处理
if(i==1)
y+=w;
else if(i==2)
y-=s;
else if(i==3)
x-=a;
}
cout<<x<<" "<<y<<endl;
}
}
四、单调环
描述
给你一个数组,下标从 1 到 n ,把它的首位相连,就形成了一个环,也就是下标为 n 的元素的下一个元素的下标为 1。
我们定义单调环为,每一个元素与其下一个元素的大小关系全部相等,很明显,除非所有数字都一样,否则无法构成单调环。
于是我们稍作修改,如果至少有 n - 1 个元素与其下一个元素的大小关系相等,我们就称它为单调环。
输入
第一行是一个正整数 T 表示测试案例的数量。(1 <= T <= 200)
每组案例先是一个正整数 n 表示数字的数量。(3 <= n <= 100)
然后是 n 个不大于 100 的正整数。
输出
针对每组案例,如果给定数组可以形成单调环则输出 YES,否则输出 NO,最后换行。
样例输入
4
5
1 1 1 1 1
5
4 5 1 2 3
5
5 4 1 2 3
3
1 1 2
样例输出
YES
YES
NO
NO
code:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
int T;
cin>>T;
int a[114];
while(T--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
int dy=0,xy=0,dd=0;//dy储存符合当前元素比下一元素大的情况,xy储存当前元素比下一元素小的情况,dd储存当前元素与下一元素相等的情况
for(int i=1;i<n;i++){
if(a[i]>a[i+1])//判断当前元素比下一元素大的情况
dy++;
else if(a[i]<a[i+1])//判断当前元素比下一元素小的情况
xy++;
else if(a[i]==a[i+1])//判断当前元素与下一元素相等的情况
dd++;
}
if(a[n]>a[1])//特判最后一个元素与第一个元素的情况
dy++;
else if(a[n]<a[1])
xy++;
else if(a[n]==a[1])
dd++;
if(dy>=n-1||xy>=n-1||dd>=n-1)
puts("YES");
else
puts("NO");
}
}
五、等差数列-3
描述
罗少有三个数字 a、b、c,他希望这三个数字可以组成一个等差数列,即 c - b = b - a。
与此同时,他拥有一个可以把数字 x 修改为数字 y 的技能,但是这个技能只能使用一次,且会消耗罗少 | x - y | 的体力。
现在罗少问你,最少需要消耗多少体力,才可以达成他的目标。
输入
第一行是一个正整数 T 表示测试案例的数量。(1 <= T <= 1000)
每组案例包含三个整数 a、b、c,表示初始时的数字。(-1000 <= a、b、c <= 1000)
输出
针对每组案例,输出罗少消耗体力的最小值,然后换行。
样例输入
2
1 2 3
4 3 1
样例输出
0
1
code:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
//通过第二个样例可以看出不能有小数
//a b c的顺序不能调换
//所以有三种情况 以b-a为公差改c 以c-b为公差改a a+c为偶数时改b 但是第一种和第二种答案是一样的 所以只要两种判断一下就行了
int main(){
int T;
cin>>T;
while(T--) {
int a,b,c;
cin>>a>>b>>c;
int d=b-a;判断b-a(c-b)为公差时需要的体力
int t=b+d;
int ans=abs(c-t);
d=a+c;
if(d%2==0)//判断a+c是否为偶数
{
ans=min(ans,abs(b-d/2));
}
cout<<ans<<endl;
}
}
六、ovo和他的汉堡店-3
描述
ovo 准备了 a 片面包和 b 片鸡肉,已知:
2 片面包 + 1 片鸡肉 = 普通汉堡,售价 x 元
3 片面包 + 2 片鸡肉 = 超级汉堡,售价 y 元
ovo 想尽可能的多赚一些钱,问:这些原材料最多可以卖出多少钱。
输入
第一行是一个正整数 T 表示测试案例的数量。(1 <= T <= 20000)
每组案例包含 4 个不大于 100 的正整数 a、b、x、y 含义如描述。
输出
针对每组样例,输出 ovo 最多可以卖出的钱,然后换行。
样例输入
2
5 3 4 6
6 4 5 8
样例输出
10
16
code:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
int T;
scanf("%d", &T);
while (T--) {
int a, b, x, y;
scanf("%d %d %d %d", &a, &b, &x, &y);
int pt = min(a / 2, b);//最多能做的普通汉堡数
int sum=0;
for (int i = 0; i <= pt; i++) {//遍历做普通汉堡数的个数
int p = min((a - 2 * i) / 3, (b - i) / 2);//做完普通汉堡剩下的材料能做的最多超级汉堡数
sum = max(x * i + y * p, sum);
}
cout << sum << endl;
}
}
七、勇者斗恶龙-5
描述
恶龙们被勇者折磨四题了,它们正在为下一次打斗做着准备。
总共有 n 条恶龙,每条龙都有一个基础攻击力 x,恶龙们找来了 m 个训练假人,当一条龙击败一个假人时,它的攻击力将会增加 x。
每条龙可以击败任意个假人,鉴于勇者经常挑软柿子捏,所以恶龙们要合理的分配这些假人,使得在训练完后,最弱的那条龙的攻击力尽可能高。
输入
第一行是两个正整数 n 和 m 分别表示恶龙的数量和假人的数量。(1 <= n <= 1e5,1 <= m <= 1e9)
然后是 n 个不大于 1e5 的正整数分别表示这 n 条龙的基础攻击力。
输出
训练完后,最弱的那条龙的攻击力最高可能是多少,然后换行。
样例输入
5 3
1 2 3 4 5
样例输出
3
code:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+14;
ll a[maxn],n,m;
bool check(ll x){
ll cnt=0;
for(int i=0;i<n;i++){
if(a[i]<x){
cnt+=(x-1)/a[i];// 向上取整原式为cnt+=(x+a[i]-a[i]-1)/a[i];
}
if(cnt>m) return 0;当前次数比n大了就不用做了防止爆ll
}
return cnt<=m;
}
//二分算法
int main(){
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>a[i];
}
ll L=1,R=1ll<<62,ans,mid;//R要比1e5大
while(L<=R){
mid=(L+R)/2;//取中间值
if(check(mid)){//是否满足需要操作的次数小于等于m
ans=mid;
L=mid+1;
}
else{
R=mid-1;
}
}
cout<<ans<<endl;
}