全国2023CSP-J普及组试题T1-T3
难度中等 比较坑的是有一元二次方程 没学过的很吃亏 我们网站的hack数据很狠 这几个代码能过 感觉还是可以的
T1-小苹果(apple)
时间限制:1000毫秒
内存限制:512MB
题目描述 Description
小 Y的桌子上放着 n 个苹果从左到右排成一列,编号为从 1到 n。
小苞是小 Y 的好朋友,每天她都会从中拿走一些苹果。
每天在拿的时候,小苞都是从左侧第 1 个苹果开始、每隔 2 个果拿走 1 个果随后小苞会将剩下的苹果按原先的顺序重新排成一列。
小苞想知道,多少天能拿完所有的苹果,而编号为 n 的苹果是在第几天被拿走的?
输入描述 Input Description
从文件 apple.in 中读入数据。
输入的第一行包含一个正整数 n,表示苹果的总数。
输出描述 Output Description
输出到文件 apple.out 中。
输出一行包含两个正整数,两个整数之间由一个空格隔开,分别表示小苞拿走所有苹果所需的天数以及拿走编号为 n 的苹果是在第几天。
样例输入 Sample Input
8
样例输出 Sample Output
5 5
数据范围及提示 Data Size & Hint
样例解释:
小苞的桌上一共放了 8 个苹果。
小苞第一天拿走了编号为 1、4、7 的苹果
小苞第二天拿走了编号为 2、6 的苹果。
小苞第三天拿走了编号为 3 的苹果
小苞第四天拿走了编号为 5 的苹果
小苞第五天拿走了编号为 8 的苹果
对于所有测试数据有: 1 < n < 109
测试点 | n ≤ | 特殊点 |
---|---|---|
1 ~ 2 | 10 | 无 |
3 ∼ 5 | 10^3 | 无 |
6 ∼ 7 | 10^6 | 有 |
8 ∼ 9 | 10^6 | 无 |
10 | 10^9 | 无 |
特殊性质:小苞第一天就取走编号为 n 的苹果
#include<bits/stdc++.h>
using namespace std;int main(){int n,day=0,ans=0;cin>>n;int m=n;while(m){day++;if(m%3==1&&!ans) ans=day;m-=(m+2)/3;}cout<<day<<" "<<ans;return 0;
}
T2-公路(road)
时间限制:1000毫秒
内存限制:512MB
题目描述 Description
小苞准备开着车沿着公路自驾。
公路上一共有 n 个站点,编号为从 1到 n。其中站点i与站点 i+1 的距离为 vi
公里;
公路上每个站点都可以加油,编号为 i 的站点一升油的价格为 ai
元,且每个站点只出售整数升的油。
小苞想从站点 1 开车到站点 n,一开始小苞在站点 1 且车的油箱是空的。已知车的油箱足够大,可以装下任意多的油,且每升油可以让车前进 d 公里。问小苞从站点 1开到站点 n,至少要花多少钱加油?
输入描述 Input Description
从文件 road.in 中读入数据。
输入的第一行包含两个正整数 n 和 d,分别表示公路上站点的数量和车每升油可以前进的距离。
输入的第二行包含 n -1个正整数 v1
, v2
… vn-1
,分别表示站点间的距离。
输入的第三行包含 n 个正整数 a1
, a2
… an
,分别表示在不同站点加油的价格。
输出描述 Output Description
输出到文件 road.out 中。
输出一行,仅包含一个正整数,表示从站点 1 开到站点 n ,小至少要花多少钱加油
样例输入 Sample Input
5 4 10 10 10 10 9 8 9 6 5
样例输出 Sample Output
79
数据范围及提示 Data Size & Hint
样例解释:最优方案下: 小苞在站点 1 买了 3 升油,在站点 2 购买了 5 升油,在站点 4 购买了 2 升油。
对于所有测试数据保证: 1< n < 105 ,1< d < 105,1< vi
< 105,1< ai
< 105
测试点 | n ≤ | 特殊点 |
---|---|---|
1 ∼ 5 | 8 | 无 |
6 ∼ 10 | 103 | 无 |
11 ∼ 13 | 105 | A |
14 ∼ 16 | 105 | B |
17 ∼ 20 | 105 | 无 |
特殊性质 A:站点 1 的油价最低
特殊性质 B:对于所有 1< i < n,vi
为 d 的倍数
T3- 一元二次方程(uqe)
时间限制:1000毫秒
内存限制:512MB
题目描述 Description
题目背景
众所周知,对一元二次方程 ax2+bx+c=0ax2+bx+c=0,(a≠0a≠0),可以用下述方式求实数解:
• 计算 Δ=b2−4acΔ=b2−4ac,则:
- 若 Δ<0Δ<0,则该一元二次方程无实数解;
- 否则 Δ≥0Δ≥0,此时该一元二次方程有两个实数解 x1,x2=−b±Δ2ax1,x2=2a−b±Δ
– 其中,ΔΔ 表示 ΔΔ 的算术平方根,即使得 s2=Δs2=Δ 的唯一非负实数 ss。
– 特别的,当 Δ=0Δ=0 时,这两个实数解相等;当 Δ>0Δ>0 时,这两个实数解互异。
例如:
• x2+x+1=0x2+x+1=0 无实数解,因为 Δ=12−4×1×1=−3<0Δ=12−4×1×1=−3<0;
• x2−2x+1=0x2−2x+1=0 有两相等实数解 x1,2=1x1,2=1;
• x2−3x+2=0x2−3x+2=0 有两互异实数解 x1=1x1=1, x2=2x2=2;
在题面描述中 aa 和 bb 的最大公因数使用 gcd(a,b)gcd(a,b) 表示。例如 1212 和 1818 的最大公因
数是 66,即 gcd(12,18)=6gcd(12,18)=6。
题目描述
现在给定一个一元二次方程的系数 aa, bb, cc,其中 aa, bb, cc 均为整数 且 a≠0a≠0。你需要判断一元二次方程 ax2+bx+c=0ax2+bx+c=0 是否有实数解,并按要求的格式输出。
在本题中输出有理数vv时须遵循以下规则:
• 由有理数的定义,存在唯一的两个整数 pp 和 qq,满足 q>0q>0,gcd(p,q)=1gcd(p,q)=1 且 v=p/qv=p/q。
• 若 q=1q=1, 则输出 {p}{p}; 否则输出 {p}/{q}{p}/{q};其中 {n}{n} 代表整数 nn 的值;
• 例如:
– 当 v=−0.5v=−0.5 时,pp 和 qq 的值分别为 −1−1 和 22,则应输出 −1/2−1/2;
– 当 v=0v=0 时,pp 和 qq 的值分别为 00 和 11,则应输出 00。
对于方程的求解,分两种情况讨论:
- 若 Δ=b2−4ac<0Δ=b2−4ac<0,则表明方程无实数解,此时你应当输出 NONO;
- 否则 Δ≥0Δ≥0,此时方程有两解(可能相等),记其中 较大者为 xx,则:
(1). 若 xx 为有理数,则按有理数的格式输出 xx。
(2). 否则根据上文公式,xx 可以被 唯一表示为 x=q1+q2rx=q1+q2r 的形式,其中:
• q1,q2q1,q2 为有理数,且 q2>0q2>0;
• rr 为正整数且 r>1r>1,且不存在正整数 d>1d>1 使 d2∣rd2∣r(即 rr 不应是 d2d2 的倍数);
此时:- 若 q1≠0q1≠0,则按照有理数的格式输出 q1q1,并再输出一个加号 ++;
- 否则跳过这一步输出;
随后:- 若 q2=1q2=1,则输出 sqrt({r})sqrt({r});
- 否则若 q2q2 为整数,则输出 {q2}∗sqrt({r}){q2}∗sqrt({r});
- 否则若 q3=1/q2q3=1/q2 为整数,则输出 sqrt({r})/{q3}sqrt({r})/{q3};
- 否则可以证明存在唯一整数 cc, dd 满足 cc, d>1d>1, gcd(c,d)=1gcd(c,d)=1 且 q2=c/dq2=c/d,此时
输出 {c}∗sqrt({r})/{d}{c}∗sqrt({r})/{d};
上述表示中 {n}{n} 代表整数 nn 的值,详见样例。
如果方程有实数解,则按要求的格式输出两个实数解中的较大者。否则若方程没有实数解,则输出 NONO。
输入描述 Input Description
从文件 uqe.in 中读入数据。
输入的第一行包含两个正整数 T, M,分别表示方程数和系数绝对值的上界;
接下来 T 行,每行包含三个整数 a, b, c。
输出描述 Output Description
输出到文件 uqe.out 中。
输出 T 行,每行包含一个字符串,表示对应询问的答案,格式如题面所述。
每行输出的字符串中间不应包含任何空格。
样例输入 Sample Input
9 1000 1 -1 0 -1 -1 -1 1 -2 1 1 5 4 4 4 1 1 0 -432 1 -3 1 2 -4 1 1 7 1
样例输出 Sample Output
1 NO 1 ‐1 ‐1/2 12*sqrt(3) 3/2+sqrt(5)/2 1+sqrt(2)/2 ‐7/2+3*sqrt(5)/2
数据范围及提示 Data Size & Hint
对于所有测试数据有:1 ≤ T ≤ 5000,1 ≤ M ≤ 103,|a|, |b|, |c| ≤ M,a ̸= 0。
测试点 | M ≤ | 特殊性质A | 特殊性质B | 特殊性质C |
---|---|---|---|---|
1 | 1 | 是 | 是 | 是 |
2 | 20 | 否 | 否 | 否 |
3 | 103 | 是 | 否 | 是 |
4 | 103 | 是 | 否 | 否 |
5 | 103 | 否 | 是 | 是 |
6 | 103 | 否 | 是 | 否 |
7,8 | 103 | 否 | 否 | 是 |
9,10 | 103 | 否 | 否 | 否 |
其中:
• 特殊性质 A:保证 b = 0;
• 特殊性质 B:保证 c = 0;
• 特殊性质 C:如果方程有解,那么方程的两个解都是整数。
#include<bits/stdc++.h>
using namespace std;int t,a,b,c,up;int main(){cin>>t>>up;while(t--){cin>>a>>b>>c;int dt=b*b-4*a*c;if(dt<0){cout<<"NO\n";continue;}if((int)sqrt(dt)*(int)sqrt(dt)==dt){int z,m=2*a;if(a<0) z=-sqrt(dt)-b;else z=sqrt(dt)-b;if(z>0&&m<0) z=-z,m=-m;if(z<0&&m<0) z=-z,m=-m;if(z%m==0) cout<<z/m;else{int g=__gcd(abs(m),abs(z));cout<<z/g<<"/"<<m/g;}}else{int uz=-b,um=2*a,z=dt;if(uz!=0){if(uz>0&&um<0) uz=-uz,um=-um;if(uz<0&&um<0) uz=-uz,um=-um;if(uz%um==0) cout<<uz/um;else{int g=__gcd(abs(um),abs(uz));cout<<uz/g<<"/"<<um/g;}cout<<"+";}int q2=1;for(int i=sqrt(dt);i>=2;i--){if(z%(i*i)==0){q2=i;z/=i*i;break;}}int g=__gcd(abs(a)*2,q2);a=abs(a)*2/g,q2/=g;if(q2==1&&a==1) cout<<"sqrt("<<z<<")";else if(q2==1) cout<<"sqrt("<<z<<")/"<<a;else if(q2%a==0) cout<<q2/a<<"*sqrt("<<z<<")";else cout<<q2<<"*sqrt("<<z<<")/"<<a;}cout<<"\n";}return 0;
}