补充
现在是2024年9月22日20:43:28,距离4月份参加完省赛已经过了5个月,当时参加省赛的代码我在官网上模拟自测了一下,得分为70(满分150),这些代码虽然写的一坨,但是在四川省b组也能拿省一等奖进国赛,甚至当时的排名还比较靠前,希望对后续参加蓝桥杯的同学有所帮助。
试题 A: 握手问题
分 | 试题 A: 握手问题 本题总分:5 分 |
---|---|
问题描述 | 小蓝组织了一场算法交流会议,总共有 50 人参加了本次会议。 在会议上,大家进行了握手交流。按照惯例他们每个人都要与除自己以外的其他所有人进行一次握手(且仅有一次)。但有 7 个人,这 7 人彼此之间没有进行握手(但这 7 人与除这 7 人以外的所有人进行了握手)。 请问这些人之间一共进行了多少次握手?注意 A 和 B 握手的同时也意味着 B 和 A 握手了,所以算作是一次握手。 |
答案提交 | 这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。 |
我的答案
#include<iostream>
#include<vector>
using namespace std;
int Solution()
{
int ans=0;
for(int i=49;i>=7;--i){
ans+=i;
cout<<i<<endl;
}
return ans;//1204
}
int main()
{
cout<<Solution();
return 0;
}
GPT答案
这个问题可以用组合数学的知识来解决。
首先,总共有 50 个人,每个人要与除自己以外的其他所有人进行一次握手,那么总的握手次数为 (502)(250)。
但是有 7 个人彼此之间没有进行握手,这意味着这 7 个人之间本应该进行 (72)(27) 次握手,但是实际上没有进行握手。
所以最终的握手次数为 (502)−(72)(250)−(27)。
计算结果为:
(502)−(72)=50×492−7×62=1225−21=1204(250)−(27)=250×49−27×6=1225−21=1204
所以最终答案为 1204。
试题 B: 小球反弹
分 | 试题 B: 小球反弹 本题总分:5 分 |
---|---|
问题描述 | 有一长方形,长为 343720 单位长度,宽为 233333 单位长度。 在其内部左上角顶点有一小球(无视其体积),其初速度如图所示且保持运动速率不变,分解到长宽两个方向上的速率之比为 dx : dy = 15 : 17。 小球碰到长方形的边框时会发生反弹,每次反弹的入射角与反射角相等, 因此小球会改变方向且保持速率不变(如果小球刚好射向角落,则按入射方向原路返回)。 从小球出发到其第一次回到左上角顶点这段时间里,小球运动的路程为多少单位长度?答案四舍五入保留两位小数。 |
答案提交 | 这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个小数,在提交答案时只填写这个小数,填写多余的内容将无法得分。 |
我的答案
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
long double Solution()
{
long double length=343720.0,width=233333.0;
long double dx=15.0,dy=17.0;
long double step=411764.1176470588;//411764
int t=0;
long double dist=0;
while(true){
t++;
dist+=step;
while(dist>length+3){
dist-=length;
}
if(abs(dist-length)<0.0001)
break;
}
cout<<"t="<<t<<endl;
cout<<"dist="<<dist<<endl;
int x=15*15;
int y=17*17;
int x_y=x+y;
double k=sqrt(x_y);
long double total=t*step;
cout<<"total="<<total<<endl;
cout<<"k="<<k<<endl;
long double ans=total*k/dx;
cout<<endl;
return ans;
}
int main()
{
cout<<fixed<<Solution();//550162599.885198
return 0;
}
这题由于太复杂gpt算不了,就不给出gpt的生成内容了
试题 C: 好数
描述 | 试题 C: 好数 时间限制: 1.0s 内存限制: 256.0MB 本题总分:10 分 |
---|---|
问题描述 | 一个整数如果按从低位到高位的顺序,奇数位(个位、百位、万位 · · · )上的数字是奇数,偶数位(十位、千位、十万位 · · · )上的数字是偶数,我们就称之 为“好数”。 给定一个正整数 N,请计算从 1 到 N 一共有多少个好数。 |
输入格式 | 一个整数 N。 |
输出格式 | 一个整数代表答案。 |
样例输入 1 | 24 |
样例输出 1 | 7 |
样例输入 2 | 2024 |
样例输出 2 | 150 |
样例说明 | 对于第一个样例,24 以内的好数有 1、3、5、7、9、21、23,一共 7 个。 |
评测用例规模与约定 | 对于 10% 的评测用例,1 ≤ N ≤ 100。对于 100% 的评测用例,1 ≤ N ≤ 1e7。 |
我的答案
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int Solution()
{
int n;
cin>>n;
int ans=0;
for(int i=1;i<=n;i+=2)
{
int dont=0;
int t=i;
bool add=true;
while(t>0){
int wei=t%10;
wei%=2;
if(wei==dont)
{
add=false;
break;
}
dont=wei;
t/=10;
}
if(add)
ans++;
}
return ans;
}
int main()
{
cout<<Solution();
return 0;
}
GPT的评价
这段代码试图统计从 1 到给定的正整数 n 之间的好数的数量。在这段代码中,它使用了一个名为
Solution
的函数来计算好数的数量。这段代码的思路是从 1 开始遍历到 n,对每个数字进行判断是否为好数。在判断是否为好数时,它使用了一个布尔变量
add
来表示当前数字是否为好数,并在遍历数字的每一位时进行更新。具体来说,它遍历了每个数字的每一位,如果相邻位上的数字奇偶性相同(即相邻位都是奇数或者都是偶数),则将add
设置为 false,表示当前数字不是好数,否则将add
设置为 true,表示当前数字是好数。最后统计所有好数的数量并返回。这段代码的逻辑是正确的,可以用于计算好数的数量。但是,它的时间复杂度较高,因为对于每个数字,需要遍历其每一位来判断奇偶性。当 n 很大时,这种方法会很慢。在实际应用中,我们通常会选择更高效的算法来解决这个问题,比如动态规划。
GPT给出的答案
我们可以使用动态规划来解决这个问题。定义一个二维数组 dp[i][j]
,其中 i
表示数字的位数,j
表示最高位数字。dp[i][j]
表示在位数为 i
时,最高位数字为 j
的好数的数量。
首先,我们需要确定状态转移方程。假设 i
位数的好数数量为 dp[i]
,则有以下几种情况:
- 如果当前位数是奇数位(个位、百位、万位…),那么当前位数的好数数量取决于前一位偶数位的好数数量,因为无论前一位的数字是什么,当前位都可以选择奇数位的数字(1、3、5、7、9)。
- 如果当前位数是偶数位(十位、千位、十万位…),那么当前位数的好数数量取决于前一位奇数位的好数数量,因为无论前一位的数字是什么,当前位都可以选择偶数位的数字(0、2、4、6、8)。
根据以上分析,我们可以得出状态转移方程:
dp[i][j] = dp[i - 1][1] + dp[i - 1][2] + dp[i - 1][3] + dp[i - 1][4] + dp[i - 1][5] + dp[i - 1][6] + dp[i - 1][7] + dp[i - 1][8] + dp[i - 1][9]
其中,如果当前位数是奇数位,则 dp[i][j]
只与前一位偶数位的好数数量有关;如果当前位数是偶数位,则 dp[i][j]
只与前一位奇数位的好数数量有关。
最后,我们将所有位数为奇数位或偶数位的好数数量相加,即为从 1 到 N 之间的好数的数量。
#include <iostream>
#include <vector>
using namespace std;
// 计算从 1 到 N 之间的好数的数量
int countGoodNumbers(int N) {
const int MOD = 1e9 + 7;
// 初始化 dp 数组
vector<vector<long long>> dp(20, vector<long long>(10, 0));
// 初始条件:1 位数时,好数的数量为 5(1、3、5、7、9)
for (int j = 1; j <= 9; ++j) {
dp[1][j] = 1;
}
// 动态规划计算好数的数量
for (int i = 2; i <= 19; ++i) {
for (int j = 1; j <= 9; ++j) {
if (i % 2 == 1) {
// 当前位数为奇数位
// 前一位是偶数位的好数数量
for (int k = 0; k <= 9; k += 2) {
dp[i][j] = (dp[i][j] + dp[i - 1][k]) % MOD;
}
} else {
// 当前位数为偶数位
// 前一位是奇数位的好数数量
for (int k = 1; k <= 9; k += 2) {
dp[i][j] = (dp[i][j] + dp[i - 1][k]) % MOD;
}
}
}
}
// 计算好数的总数量
long long ans = 0;
for (<