ACGO欢乐赛#39全题解来咯
2025-01-21 18:15:24
发布于:上海
励志做全ACGO最优秀的欢乐赛优秀题解发布员
(至于为什么没有及时了,本人认为追求速度之前应该先追求质量)
前言:
第二次写题解了,至于为什么欢乐赛#38没写题解,主要是作者水平有点菜,没有AK,所以没写题解...
本人认为本次题目难度还算可以,难度不算高
个人认为难度:红 红 红 橙 红 红
ok废话不多,进入题解部分:
(会搞链接了哈哈)
T1:
题目名称:取模运算
时间限制:1.00s
内存限制:128MB
题目描述:
求 (114514 mod 1919810) + (1919810 mod 114514) 的结果
思路分析:
很简单,直接在cout后面跟着求,把mod替换为%就行
代码部分:
#include<bits/stdc++.h>
using namespace std;
int main()
{
cout<<(114514%1919810) + (1919810%114514);
}
注意事项:
没啥好注意的 结果不会爆int,不用先乘1LL
T2:
题目名称:2的若干次方
时间限制:1.00s
内存限制:128MB
题目描述:
给一个数n,求2的n次方
思路分析:
用 递推 或者 for循环 一次一次乘都可以
代码部分:
方法一:
递推
#include<iostream>
using namespace std;
int main()
{
int a[30],n;
a[0]=1;
for(int i=1;i<=25;i++)
{
a[i]=a[i-1]*2; //递推式
}
cin>>n;
cout<<a[n];
}
方法二:
for循环
#include<iostream>
using namespace std;
int main()
{
int a=1;
int n;
cin>>n;
for(int i=0;i<n;i++)
{
a*=2;
}
cout<<a;
}
注意事项:
注意2的0次方是1,然后后面每次乘2,20次方不会爆int,不要浪费空间
两个方法都要注意
T3:
题目名称:下棋
时间限制:1.00s
内存限制:128MB
题目描述:
有一个 1 × m 的棋盘,初始时没有旗子。现在有 n 次操作,每次操作尝试在棋盘的第 (1, ai) 位置放置一颗棋子。放置规则如下:
如果第 (1,a[i]) 位置已有棋子,则尝试将棋子放到第 (1, a[i+1]) 位置。
如果第 (1,a[i+1]) 的位置也有旗子,则该次操作不会产生任何效果。
请问最后棋盘上棋子的数量?
思路分析:
这题很简单,因为是 1 × m 的棋盘,所以直接用一维数组即可
对于放置规则,可能有人直接在那个位置+1,但是要考虑到往后挪,所以需要改进
代码部分:
#include<iostream>
using namespace std;
int a[200010];
int main()
{
int m,n,sum=0;;
cin>>m>>n;
for(int i=0;i<n;i++)
{
int x;
cin>>x;
if(!a[x])
{
a[x]=1;
sum++;
}
else if(a[x] and !a[x+1] and x+1<=m)
{
a[x+1]=1;
sum++;
}
else continue;
//其实我觉得这里还有一种解法,就是每次如果往后挪了就直接+1
//然后最后的时候循环遍历一遍数组,大于1的给sum+1
}
cout<<sum;
}
注意事项:
照着题目来就行
T4:
题目名称:ABC游戏
时间限制:1.00s
内存限制:128MB
题目描述:
给定三个整数 A, B, C,你可以执行以下两种操作:
操作 1:选择两个数,对这两个数各加 1。
操作 2:选择一个数,对这个数加 2。
你的目标是将 A, B, C 三个数变成相同的,问你至少需要执行多少次操作?
思路分析:
这道题对于思维还是有点考验的
首先我们要想明白一件事: 怎么去用最少的步数把两个数变成一样的
我给两张图就可以明白了
(首先先要排序)
图一:
图二:
(第一次画图,画的不太好)
可能有人问啊:啊青莛青莛 这两张图有啥用?
很简单:第二个数和第一个数是奇数差(图1)还是偶数差(图2)
然后第一个数和第二个数补齐之后,基准和第三个数是奇数差(图1)还是偶数差(图2)
那如果数字大了怎么办呢?补2不就行了
思路梳理结束,直接上代码:
代码部分:
#include<iostream>
#include<algorithm>
using namespace std;
bool cmp(int x,int y)
{
return x>y;
}
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
{
int m[5];
int sum=0;
cin>>m[0]>>m[1]>>m[2]; //输入进列表里,方便排序
sort(m,m+3,cmp); //排序
int a=m[0],b=m[1],c=m[2];
int ab=a-b,bc;
if(ab%2==0)
{
sum+=ab/2;
b=a;
}
else
{
sum+=ab/2+1;
b=a;
c++;
}
//求出数1和数2的差,然后看奇偶,对应两种不同的操作
bc=b-c; //求现在差
if(bc%2==0) sum+=bc/2;
else sum+=bc/2+2;
//同理,判断奇偶
cout<<sum<<endl;
}
}
注意事项:
想明白补齐第二个数和补齐第三个数两种情况分别要用多少步,最后叠加,然后输出
T5:
题目名称:看海
时间限制:1.00s
内存限制:128MB
题目描述:
有 N 座山从西到东排布,最西面是大海。
每座山的山顶上都有一家客栈。你决定选择其中一座山的客栈下榻。
从最西边的山顶开始,你可以看到大海。对于从西面看第 i 座山的客栈,你能够看到大海,前提是从第 1 座山到第 i-1 座山的山顶高度都不高于第 i 座山的山顶高度。
你的任务是计算一共有多少座山的客栈可以看到大海?
思路分析:
怎么说呢,这题归类到入门不是没道理的,就是创建一个最大值,从左到右遍历,比最大值大/和最大值相等 就计数器+1,然后最大值为这个山的高度,小就直接跳过。
代码部分:
#include<iostream>
using namespace std;
int main()
{
int n,m=0;
cin>>n;
int sum=0;
for(int i=0;i<n;i++)
{
int x;
cin>>x;
if(x>=m)
{
sum++;
m=x;
}
}
cout<<sum;
}
注意事项:
其实没什么好注意的,我是直接在输入的时候做判断,也可以存入列表然后遍历+判断
就是一个点要注意,判断能不能看到是大于等于,不是大于
T6:
题目名称:打牌
时间限制:1.00s
内存限制:128MB
题目描述:
小王和小美一起在打牌,一开始两个人都有两张扑克牌,刚开始的扑克牌都是正面朝下。
游戏一共两个回合。在每一回合游戏里,小王和小美都随机选择一张未反转的牌将其翻转,两张牌中数据更大的人能赢下这个回合,且赢的回合数多的人赢得整场游戏,如果赢的回合数一样多,就是平局。
问小王赢得这场游戏的方式有几种?
思路分析:
怎么说呢,这题其实不是很难,有人难度给橙,我觉得只有红,想明白就很简单
输入应该不用我解释
判断就把先翻第一张的两种情况判断,然后再分支判断,最后乘2(先翻第一张,然后翻第二张,和先翻第二张,再翻第一张都一样,所以乘2)
判断的时候最好有等于防止特殊情况
代码部分:
#include<iostream>
using namespace std;
int main()
{
int t;
cin>>t;
for(int ut=0;ut<t;ut++)
{
int a,b,c,d;
cin>>a>>b>>c>>d;
int sum=0;
if(a>c)
{
if(b>=d) sum++;
}
if(a==c)
{
if(b>d) sum++;
}
if(a>d)
{
if(b>=c) sum++;
}
if(a==d)
{
if(b>c) sum++;
}
cout<<sum*2<<endl;
}
}
是不是还挺简单,其实弄明白思路就是这样(和第四题一样)
注意事项:
前面也提醒了,判断的时候最好有等于,防止特殊情况
废话 结语环节:
欢乐赛#38没写题解,主要是还没弄明白,然后也祝贺自己#37的题解上优秀题解了,作者也会继续改进自己的题解和技术
走过路过点个赞吧,写题解真的很不容易啊(放到word里390多行啊)
这次的题解就到这里,下期欢乐赛学习讨论再见
这里空空如也
有帮助,赞一个