CSP游记(题解?)

CSP游记

题解在这儿

本文主要总结2023年CSP的参赛体验

既帮助自己明年(或许吧)CSP发挥

也可以帮助一些没参赛的读者了解过程、精准备赛

一、初赛备赛

CSP报名从7月17日00时00分起,9月7日15时00分止 。

但是我实际报名好像是七月中旬报的。并不重要

之后就是刷题、刷题、刷题、刷题、刷题……

这个时候感觉还不错,虽然有一点紧张。

题做得不少,时间也花了,已经尽力了
明年可能还需要对着清单再复习一遍,学习没学的知识点

【图1-1】
二、初赛
J组
  • 赛前

先说 J 吧,毕竟是上午考的。

考试前非常紧张,觉都没睡好。

第二天一醒来,慢慢吃了个饭(都没吃好,也许是太紧张了),然后就进考场了。

进到考场,是熟悉的综合教室,放松了一点,还和同学有说有笑。

笑那些小学组来打酱油的。

或许别人也是这么笑我的。

  • 环境

    一进门就是一个摄像机对着,考场里还有更多。

    根据监考老师介绍,本场考试有信号屏蔽器。

    不起眼的地方摆着一个箱子,之前都没有,应该就是了。

  • 开始宣读考试规则

    大概30min以后,老师开始宣读考试规则。都是考试的正常环节了,感觉还是挺放松的。

  • 发答题卡和试卷,正式开始考试

    考试过程中有几道题不会,没有过多思考,直接跳到下一题。

    有几道题最后都不确定,分值不重,也没继续消耗时间。

    答题的最后一题二分确实让我很不确定。

    虽然考前都看过了,也知道二分细节很多,但是实际问题怎么都做不对。

    再回到考试。

    当时我真的犹豫了很久,毕竟错一个其他的都对不了。

    走出考场的时候有点慌。

    最后成绩是69分,虽然刚刚高过分数线,但是肯定二分那块基本全错。

最终成绩有些不理想,即使进入第二轮,还是发挥得不好

S组

J J J组几乎一样的感受,只是题难了不少,很多都不会,全靠蒙,连蒙带猜。

其它的


好像没什么好讲的了。蒟蒻没有体验

还是等明年吧。

自我感觉是正常发挥,可能八字差了一点

J 组多了2.5分,S 组少了2分……

重庆分数线居然调高了,要不然就能进复赛……

放个图吧

J组:

【图1-2】

S组:

【图1-3】

总的来说,初赛还是发挥得可以。

S组就等明年吧。

三、复赛备赛

初赛一考完得到成绩,几乎立刻就进入了紧张的复赛备赛阶段。

几乎每天就是考试、考试、考试。

自习也几乎没上全过,都在补题、考试。

马上就是期中了,虽然复赛在期中之前,时间还是有点紧。

当然,不停的做牛客、洛谷的题,也有好处。

比如:了解了题目里中文负号(‘-’)和英文负号(‘-’)的区别……。

其它见算法竞赛:闭坑指南

【图1-4】

四、复赛

题面来自这里

CSP-J题面

  • 赛前

    认证点的机房在其他校区,前一周试过机,反而有点熟悉。

    只不过心跳有点快。

  • 环境

    每个人之间都有一个白色的挡板,上面是“XX认证点”字样(好像是吧)。

    虽然座位中间没有空,可能因为机房太小了。

    所以身体往后靠也是可以看到别人电脑的一小部分的。(我当然没看)

    大样例已经在电脑里了,Windows下的F盘,Linux下的share文件夹。

    名字也有(英文)。

    然后就是把T1~T4的源文件打好,比如freopen之类的。

    最开始,我打的所有源文件都是T4那样的,因为我考试的时候没动T4。

  • 开始宣读考试规则

    这次有点紧张,和第一轮完全不一样。

    提前5min发压缩包密码,是用一个图标是眼睛的软件发的,没见过。

    收文件的软件是cena。

  • 正式开始考试

    老师念了几遍PDF的密码,然后写在黑板上。

    题面的PDF一开始就在压缩包里,只是每次打开都需要密码。

    开始考试。

T1 小苹果(apple)

题目描述

小 Y 的桌子上放着 n n n 个苹果从左到右排成一列,编号为从 1 1 1 n n n

小苞是小 Y 的好朋友,每天她都会从中拿走一些苹果。

每天在拿的时候,小苞都是从左侧第 1 1 1 个苹果开始、每隔 2 2 2 个苹果拿走 1 1 1 个苹果。随后小苞会将剩下的苹果按原先的顺序重新排成一列。

小苞想知道,多少天能拿完所有的苹果,而编号为 n n n 的苹果是在第几天被拿走的?

输入格式

输入的第一行包含一个正整数 n n n,表示苹果的总数。

输出格式

输出一行包含两个正整数,两个整数之间由一个空格隔开,分别表示小苞拿走所有苹果所需的天数以及拿走编号为 n n n 的苹果是在第几天。

样例 #1

样例输入 #1

8

样例输出 #1

5 5

提示

【样例 1 1 1 解释】

小苞的桌上一共放了 8 8 8 个苹果。

小苞第一天拿走了编号为 1 1 1 4 4 4 7 7 7 的苹果。

小苞第二天拿走了编号为 2 2 2 6 6 6 的苹果。

小苞第三天拿走了编号为 3 3 3 的苹果。

小苞第四天拿走了编号为 5 5 5 的苹果。

小苞第五天拿走了编号为 8 8 8 的苹果。

【样例 2 2 2

见选手目录下的 apple/apple2.in 与 apple/apple2.ans。

【数据范围】

对于所有测试数据有: 1 ≤ n ≤ 1 0 9 1\leq n\leq 10^9 1n109

测试点 n ≤ n\leq n特殊性质
1 ∼ 2 1\sim 2 12 10 10 10
3 ∼ 5 3\sim 5 35 1 0 3 10^3 103
6 ∼ 7 6\sim 7 67 1 0 6 10^6 106
8 ∼ 9 8\sim 9 89 1 0 6 10^6 106
10 10 10 1 0 9 10^9 109

特殊性质:小苞第一天就取走编号为 n n n 的苹果。


急速看完T1,然后开始推公式。

推公式这里要说一下。

一般思维题我推公式都是在草稿纸上画表格。

最开始做这种题的时候没有思路,一会就放弃。

后来题做多了,找到方法,毕竟多推推总是能想出来的。

不过每次都要推很久,这次也不例外。

大概用了一个多小时,终于发现规律了。太慢了

飞速打完,一测样例。

紧张。

凸(艹皿艹 )

。。。

然后只能继续推公式。

又推一次。

又是十几分钟过去了。。。

又飞速打完,又一测样例。

又紧张。

过了。

但我还不放心,自己又造了几组数据,全都过了,这才放心,很可能AC。

换下一题


思路:

模拟。

n(也可以再定义一个变量)每次减去 ⌈ n 3 ⌉ \lceil \frac{n}{3} \rceil 3n

如果当前n%3=1,就是答案。

注意第9行特判第一次。

评测code:

考试最后1s的提交代码,即交到CCF评测的代码

纯考试代码,没有任何修改,连多的tab都没删

后文同

#include <cstdio>

int main(){
	freopen("apple.in","r",stdin);
	freopen("apple.out","w",stdout);
	
	int n;
	scanf("%d",&n);

	int tmp=n,cnt=0,ans=0;
	for(;tmp;){
		if(!ans&&tmp%3==1)
			ans=cnt+1;
		tmp-=(tmp+2)/3;
		cnt++;
	}

	printf("%d %d",cnt,ans);
}

code:

考试后的AC代码

后文同

#include <cstdio>

int main() {
	int n;
	scanf("%d", &n);

	int tmp = n, cnt = 0, ans = 0;
	for (; tmp; cnt++) {
		if (!ans && tmp % 3 == 1)
			ans = cnt + 1;
		tmp -= (tmp + 2) / 3;
	}

	printf("%d %d", cnt, ans);
}

T1虽然AC,但耗了非常多的时间。

以后应该多练练思维题

立个flag:

  • 练习30道思维题

T2 公路(rode)

题目描述

小苞准备开着车沿着公路自驾。

公路上一共有 n n n 个站点,编号为从 1 1 1 n n n。其中站点 i i i 与站点 i + 1 i + 1 i+1 的距离为 v i v_i vi 公里。

公路上每个站点都可以加油,编号为 i i i 的站点一升油的价格为 a i a_i ai 元,且每个站点只出售整数升的油。

小苞想从站点 1 1 1 开车到站点 n n n,一开始小苞在站点 1 1 1 且车的油箱是空的。已知车的油箱足够大,可以装下任意多的油,且每升油可以让车前进 d d d 公里。问小苞从站点 1 1 1 开到站点 n n n,至少要花多少钱加油?

输入格式

输入的第一行包含两个正整数 n n n d d d,分别表示公路上站点的数量和车每升油可以前进的距离。

输入的第二行包含 n − 1 n - 1 n1 个正整数 v 1 , v 2 … v n − 1 v_1, v_2\dots v_{n-1} v1,v2vn1,分别表示站点间的距离。

输入的第三行包含 n n n 个正整数 a 1 , a 2 … a n a_1, a_2 \dots a_n a1,a2an,分别表示在不同站点加油的价格。

输出格式

输出一行,仅包含一个正整数,表示从站点 1 1 1 开到站点 n n n,小苞至少要花多少钱加油。

样例 #1

样例输入 #1

5 4
10 10 10 10
9 8 9 6 5

样例输出 #1

79

提示

【样例 1 解释】

最优方案下:小苞在站点 1 1 1 买了 3 3 3 升油,在站点 2 2 2 购买了 5 5 5 升油,在站点 4 4 4 购买了 2 2 2 升油。

【样例 2】

见选手目录下的 road/road2.in 与 road/road2.ans。

【数据范围】

对于所有测试数据保证: 1 ≤ n ≤ 1 0 5 1 \leq n \leq 10^5 1n105 1 ≤ d ≤ 1 0 5 1 \leq d \leq 10^5 1d105 1 ≤ v i ≤ 1 0 5 1 \leq v_i \leq 10^5 1vi105 1 ≤ a i ≤ 1 0 5 1 \leq a_i \leq 10^5 1ai105

测试点 n ≤ n \leq n特殊性质
1 ∼ 5 1\sim 5 15 8 8 8
6 ∼ 10 6\sim 10 610 1 0 3 10^3 103
11 ∼ 13 11\sim 13 1113 1 0 5 10^5 105A
14 ∼ 16 14\sim 16 1416 1 0 5 10^5 105B
17 ∼ 20 17\sim 20 1720 1 0 5 10^5 105
  • 特殊性质 A:站点 1 1 1 的油价最低。
  • 特殊性质 B:对于所有 1 ≤ i < n 1 \leq i < n 1i<n v i v_i vi d d d 的倍数。

一开始看到这道题:

这不贪心吗?哇!太简单了!

从最开始直接跳到油价最小的地方smin就行了!

自信!样例都不用模拟!

如果smin是开始或者最后,可以加个特判。

写着写着,好像又不用特判。

写完,自信测样例!

。。。

凸(艹皿艹 )

好吧,只好又推一遍。

这次看了下样例,推了一下过程。

观察规律,然后……灵机一动~

聪明的我 立马就发现最优策略应该是跳到后面第一个比当前油价低的加油站。

然后就开打了。

写啊

写啊

写啊

终于写完了

ヽ( ̄▽ ̄)ノ

再测样例

(;´д`)ゞ

再各种输出中间变量,终于发现——

٩(º﹃º٩)

应该开double。

本来读题的时候是想到了的,也提醒自己要开double。

读着读着,想着想着,算着算着,打着打着。。。

就忘了

这也是经常容易犯的一个错误。

言归正传。

然后,就是漫长的修改。。。

29~32行那里每行都改了至少3次以上,还不算移行等操作。

唉。


思路:

贪心。

每次跳到后面第一个比当前油价低的加油站。

注意浮点数的细节问题。

评测code:

#include <cstdio>

int v[100003],a[100003];

int main(){
	freopen("road.in","r",stdin);
	freopen("road.out","w",stdout);
	
	int n,d;
	scanf("%d%d",&n,&d);
	for(int i=1;i<n;i++) scanf("%d",v+i);
	for(int i=1;i<=n;i++) scanf("%d",a+i);

	double now=0,need;
	long long ans=0,add,dis;
	int pre,nxt=1;
	while(nxt!=n+1){
		pre=nxt;
		for(int i=nxt+1;i<=n+1;i++)
			if(a[i]<a[nxt]){
				nxt=i;
				break;
			}

		dis=0;
		for(int i=pre;i<nxt;i++)
			dis+=v[i];

		need=(double)dis/d;
		add=need-now+0.999999;
		now+=add-need;
		ans+=add*a[pre];
	}

	printf("%lld",ans);
}

code:(几乎没改,只是格式化了一下 本来就很完美

#include <cstdio>

int v[100003], a[100003];

int main() {
	int n, d;
	scanf("%d%d", &n, &d);
	for (int i = 1; i < n; i++) scanf("%d", v + i);
	for (int i = 1; i <= n; i++) scanf("%d", a + i);

	double now = 0, need;
	long long ans = 0, add, dis;
	int pre, nxt = 1;
	while (nxt != n + 1) {
		pre = nxt;
		for (int i = nxt + 1; i <= n + 1; i++)
			if (a[i] < a[nxt]) {
				nxt = i;
				break;
			}

		dis = 0;
		for (int i = pre; i < nxt; i++)
			dis += v[i];

		need = (double)dis / d;
		add = need - now + 0.999999;
		now += add - need;
		ans += add * a[pre];
	}

	printf("%lld", ans);
}

感觉是考场上最完美的一道了

除了耗时多一点,其他都还好

T3 一元二次方程(uqe)

题目背景

众所周知,对一元二次方程 a x 2 + b x + c = 0 , ( a ≠ 0 ) ax ^ 2 + bx + c = 0, (a \neq 0) ax2+bx+c=0,(a=0),可以用以下方式求实数解:

  • 计算 Δ = b 2 − 4 a c \Delta = b ^ 2 - 4ac Δ=b24ac,则:
    1. Δ < 0 \Delta < 0 Δ<0,则该一元二次方程无实数解。
      2. 否则 Δ ≥ 0 \Delta \geq 0 Δ0,此时该一元二次方程有两个实数解 x 1 , 2 = − b ± Δ 2 a x _ {1, 2} = \frac{-b \pm \sqrt \Delta}{2a} x1,2=2ab±Δ

例如:

  • x 2 + x + 1 = 0 x ^ 2 + x + 1 = 0 x2+x+1=0 无实数解,因为 Δ = 1 2 − 4 × 1 × 1 = − 3 < 0 \Delta = 1 ^ 2 - 4 \times 1 \times 1 = -3 < 0 Δ=124×1×1=3<0
  • x 2 − 2 x + 1 = 0 x ^ 2 - 2x + 1 = 0 x22x+1=0 有两相等实数解 x 1 , 2 = 1 x _ {1, 2} = 1 x1,2=1
  • x 2 − 3 x + 2 = 0 x ^ 2 - 3x + 2 = 0 x23x+2=0 有两互异实数解 x 1 = 1 , x 2 = 2 x _ 1 = 1, x _ 2 = 2 x1=1,x2=2

在题面描述中 a a a b b b 的最大公因数使用 gcd ⁡ ( a , b ) \gcd(a, b) gcd(a,b) 表示。例如 12 12 12 18 18 18 的最大公因数是 6 6 6,即 gcd ⁡ ( 12 , 18 ) = 6 \gcd(12, 18) = 6 gcd(12,18)=6

题目描述

现在给定一个一元二次方程的系数 a , b , c a, b, c a,b,c,其中 a , b , c a, b, c a,b,c 均为整数且 a ≠ 0 a \neq 0 a=0。你需要判断一元二次方程 a x 2 + b x + c = 0 a x ^ 2 + bx + c = 0 ax2+bx+c=0 是否有实数解,并按要求的格式输出。

在本题中输出有理数 v v v 时须遵循以下规则:

  • 由有理数的定义,存在唯一的两个整数 p p p q q q,满足 q > 0 q > 0 q>0 gcd ⁡ ( p , q ) = 1 \gcd(p, q) = 1 gcd(p,q)=1 v = p q v = \frac pq v=qp

  • q = 1 q = 1 q=1则输出 {p},否则输出 {p}/{q},其中 {n} 代表整数 n n n 的值;

  • 例如:

    • v = − 0.5 v = -0.5 v=0.5 时, p p p q q q 的值分别为 − 1 -1 1 2 2 2,则应输出 -1/2
    • v = 0 v = 0 v=0 时, p p p q q q 的值分别为 0 0 0 1 1 1,则应输出 0

对于方程的求解,分两种情况讨论:

  1. Δ = b 2 − 4 a c < 0 \Delta = b ^ 2 - 4ac < 0 Δ=b24ac<0,则表明方程无实数解,此时你应当输出 NO

  2. 否则 Δ ≥ 0 \Delta \geq 0 Δ0,此时方程有两解(可能相等),记其中较大者为 x x x,则:

    1. x x x 为有理数,则按有理数的格式输出 x x x

    2. 否则根据上文公式, x x x 可以被唯一表示为 x = q 1 + q 2 r x = q _ 1 + q _ 2 \sqrt r x=q1+q2r 的形式,其中:

  • q 1 , q 2 q _ 1, q _ 2 q1,q2 为有理数,且 q 2 > 0 q _ 2 > 0 q2>0

  • r r r 为正整数且 r > 1 r > 1 r>1,且不存在正整数 d > 1 d > 1 d>1 使 d 2 ∣ r d ^ 2 \mid r d2r(即 r r r 不应是 d 2 d ^ 2 d2 的倍数);

    此时:

    1. q 1 ≠ 0 q _ 1 \neq 0 q1=0,则按有理数的格式输出 q 1 q _ 1 q1,并再输出一个加号 +
    2. 否则跳过这一步输出;

    随后:

    1. q 2 = 1 q _ 2 = 1 q2=1,则输出 sqrt({r})
    2. 否则若 q 2 q _ 2 q2 为整数,则输出 {q2}*sqrt({r})
    3. 否则若 q 3 = 1 q 2 q _ 3 = \frac 1{q _ 2} q3=q21 为整数,则输出 sqrt({r})/{q3}
    4. 否则可以证明存在唯一整数 c , d c, d c,d 满足 c , d > 1 , gcd ⁡ ( c , d ) = 1 c, d > 1, \gcd(c, d) = 1 c,d>1,gcd(c,d)=1 q 2 = c d q _ 2 = \frac cd q2=dc,此时输出 {c}*sqrt({r})/{d}

    上述表示中 {n} 代表整数 {n} 的值,详见样例。

    如果方程有实数解,则按要求的格式输出两个实数解中的较大者。否则若方程没有实数解,则输出 NO

输入格式

输入的第一行包含两个正整数 T , M T, M T,M,分别表示方程数和系数的绝对值上限。

接下来 T T T 行,每行包含三个整数 a , b , c a, b, c a,b,c

输出格式

输出 T T T 行,每行包含一个字符串,表示对应询问的答案,格式如题面所述。

每行输出的字符串中间不应包含任何空格

样例 #1

样例输入 #1

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

样例输出 #1

1
NO
1
-1
-1/2
12*sqrt(3)
3/2+sqrt(5)/2
1+sqrt(2)/2
-7/2+3*sqrt(5)/2

提示

【样例 #2】

见附件中的 uqe/uqe2.inuqe/uqe2.ans

【数据范围】

对于所有数据有: 1 ≤ T ≤ 5000 1 \leq T \leq 5000 1T5000 1 ≤ M ≤ 1 0 3 1 \leq M \leq 10 ^ 3 1M103 ∣ a ∣ , ∣ b ∣ , ∣ c ∣ ≤ M |a|,|b|,|c| \leq M a,b,cM a ≠ 0 a \neq 0 a=0

测试点编号 M ≤ M \leq M特殊性质 A特殊性质 B特殊性质 C
1 1 1 1 1 1
2 2 2 20 20 20
3 3 3 1 0 3 10 ^ 3 103
4 4 4 1 0 3 10 ^ 3 103
5 5 5 1 0 3 10 ^ 3 103
6 6 6 1 0 3 10 ^ 3 103
7 , 8 7, 8 7,8 1 0 3 10 ^ 3 103
9 , 10 9, 10 9,10 1 0 3 10 ^ 3 103

其中:

  • 特殊性质 A:保证 b = 0 b = 0 b=0

  • 特殊性质 B:保证 c = 0 c = 0 c=0

  • 特殊性质 C:如果方程有解,那么方程的两个解都是整数。


先叫亿声——

啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊

就是因为这个可恶的T3大模拟!!

本来的一等奖多了一横!!!

我恨T3!!!

我恨T3!!!

我恨T3!!!

我恨大模拟!!!

我恨大模拟!!!

我恨大模拟!!!

我恨T3大模拟!!!

我恨T3大模拟!!!

我恨T3大模拟!!!

唉。。。

考场上没什么可以说的,直接看题,开打。

中间改了几次代码结构,关键我前面写的没改回来!!!

就是因为41、43行,只要改成out_fra函数再加个puts(“”)就能A了!!!

直接少了50分!!!

啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊

如果非要说的话,把样例复制到编译器的时候感觉有点不对。

一看,居然是中文负号!!!

还好模拟赛的时候被坑过

here


思路:

不想写了,没心情。

题目已经说得清清楚楚了。

评测code:

#include <cstdio>
#include <cmath>

int Abs(int x){return x>0?x:-x;}
int Gcd(int x,int y){return !y?x:Gcd(y,x%y);}
void out_fra(int a,int b){
	bool f=0;
	if(a*b<0) f=1;
	a=Abs(a),b=Abs(b);
	int GCD=Gcd(a,b);
	
	if(f) putchar('-');
	a/=GCD,b/=GCD;
	printf("%d",a);
	if(b!=1) printf("%d",b);
}

int main(){
	freopen("uqe.in","r",stdin);
	freopen("uqe.out","w",stdout);

	int t,m,a,b,c;
	scanf("%d%d",&t,&m);
	
	int derta;
	while(t--){
		scanf("%d%d%d",&a,&b,&c);

		derta=b*b-4*a*c;
		if(derta<0){
			puts("NO");
			continue;
		}else if(derta==0){
			out_fra(-b,2*a);
			puts("");
			continue;
		}
		int sq=sqrt(derta);
		if(sq*sq==derta){
			if(a>0)
				printf("%d\n",(-b+sq)/2/a);
			else
				printf("%d\n",(-b-sq)/2/a);
			continue;
		}
		
		bool q1=0;
		if(b){
			out_fra(-b,2*a);
			q1=1;
		} // output q1


		int tmp=derta,res=1,remain=1;
		for(int i=2;i*i<=derta&&tmp>1;i++){
			while(tmp%(i*i)==0)
				res*=i,tmp/=i*i;
			if(tmp%i==0) tmp/=i,remain*=i;
		} // derta=res*res *tmp  (max{res})
		if(tmp>1) remain*=tmp;

		bool q2=0,r=0;

		if(a>0){
			if(q1) putchar('+');
		}else
			putchar('-');
		if(a<0) a=-a;
		int g=Gcd(res,2*a);
		int out1=res/g,out2=2*a/g;
		if(out1>1)
			printf("%d",out1),q2=1;
		if(remain>1){
			r=1;
			if(q2) putchar('*');
			printf("sqrt(%d)",remain);
		}
		if(!q2&&!r) putchar('1');
		if(out2>1)
			printf("/%d",out2);

		puts("");
	}
}

code:

#include <cstdio>
#include <cmath>

inline int Abs(const int&x) {return x > 0 ? x : -x;}
inline int Gcd(const int&x, const int&y) {return !y ? x : Gcd(y, x % y);}
inline void out_fra(int a, int b) {
	if (a * b < 0) putchar('-');

	a = Abs(a), b = Abs(b);
	int g = Gcd(a, b);
	a /= g, b /= g;
	printf("%d", a);
	if (b != 1) printf("/%d", b);
}

int main() {
	int t, m, a, b, c;
	scanf("%d%d", &t, &m);

	while (t--) {
		scanf("%d%d%d", &a, &b, &c);

		int delta = b * b - 4 * a * c;
		if (delta < 0) {
			puts("NO");
			continue;
		} else if (delta == 0) {
			out_fra(-b, 2 * a);
			puts("");
			continue;
		}
		int sq = (int)sqrt(delta);
		if (sq * sq == delta) {
			if (a > 0)
				out_fra(-b + sq, 2 * a);
			else
				out_fra(-b - sq, 2 * a);
			puts("");
			continue;
		}

		bool q1 = 0;
		if (b) {
			out_fra(-b, 2 * a);
			q1 = 1;
		} // output q1


		int tmp = delta, res = 1, rem = 1;
		for (int i = 2; i * i <= delta && tmp > 1; i++) {
			while (tmp % (i * i) == 0)
				res *= i, tmp /= i * i;
			if (tmp % i == 0) tmp /= i, rem *= i;
		} // delta=res*res *tmp  (max{res})
		if (tmp > 1) rem *= tmp;

		bool q2 = 0, r = 0;

		if (a < 0) a = -a;
		if (q1) putchar('+');
		int g = Gcd(res, 2 * a);
		int out1 = res / g, out2 = 2 * a / g;
		if (out1 > 1)
			printf("%d", out1), q2 = 1;
		if (rem > 1) {
			r = 1;
			if (q2) putchar('*');
			printf("sqrt(%d)", rem);
		}
		if (!q2 && !r) putchar('1');
		if (out2 > 1)
			printf("/%d", out2);

		puts("");
	}
}

我恨大模拟!!!

定个小目标:

  • 完成30道大模拟

别问,问就是喜欢30

T4 旅游巴士(bus)

题目描述

小 Z 打算在国庆假期期间搭乘旅游巴士去一处他向往已久的景点旅游。

旅游景点的地图共有 n n n 处地点,在这些地点之间连有 m m m 条道路。其中 1 1 1 号地点为景区入口, n n n 号地点为景区出口。我们把一天当中景区开门营业的时间记为 0 0 0 时刻,则从 0 0 0 时刻起,每间隔 k k k 单位时间便有一辆旅游巴士到达景区入口,同时有一辆旅游巴士从景区出口驶离景区。

所有道路均只能单向通行。对于每条道路,游客步行通过的用时均为恰好 1 1 1 单位时间。

小 Z 希望乘坐旅游巴士到达景区入口,并沿着自己选择的任意路径走到景区出口,再乘坐旅游巴士离开,这意味着他到达和离开景区的时间都必须是 k k k 的非负整数倍。由于节假日客流众多,小 Z 在旅游巴士离开景区前只想一直沿着景区道路移动,而不想在任何地点(包括景区入口和出口)或者道路上停留

出发前,小 Z 忽然得知:景区采取了限制客流的方法,对于每条道路均设置了一个
“开放时间” a i a _ i ai,游客只有不早于 a i a _ i ai 时刻才能通过这条道路。

请帮助小 Z 设计一个旅游方案,使得他乘坐旅游巴士离开景区的时间尽量地早。

输入格式

输入的第一行包含 3 个正整数 n , m , k n, m, k n,m,k,表示旅游景点的地点数、道路数,以及旅游巴士的发车间隔。

输入的接下来 m m m 行,每行包含 3 个非负整数 u i , v i , a i u _ i, v _ i, a_ i ui,vi,ai,表示第 i i i 条道路从地点 u i u _ i ui 出发,到达地点 v i v _ i vi,道路的“开放时间”为 a i a _ i ai

输出格式

输出一行,仅包含一个整数,表示小 Z 最早乘坐旅游巴士离开景区的时刻。如果不存在符合要求的旅游方案,输出 -1

样例 #1

样例输入 #1

5 5 3
1 2 0
2 5 1
1 3 0
3 4 3
4 5 1

样例输出 #1

6

提示

【样例 #1 解释】

小 Z 可以在 3 3 3 时刻到达景区入口,沿 1 → 3 → 4 → 5 1 \to 3 \to 4 \to 5 1345 的顺序走到景区出口,并在 6 6 6 时刻离开。

【样例 #2】

见附件中的 bus/bus2.inbus/bus2.ans

【数据范围】

对于所有测试数据有: 2 ≤ n ≤ 1 0 4 2 \leq n \leq 10 ^ 4 2n104 1 ≤ m ≤ 2 × 1 0 4 1 \leq m \leq 2 \times 10 ^ 4 1m2×104 1 ≤ k ≤ 100 1 \leq k \leq 100 1k100 1 ≤ u i , v i ≤ n 1 \leq u _ i, v _ i \leq n 1ui,vin 0 ≤ a i ≤ 1 0 6 0 \leq a _ i \leq 10 ^ 6 0ai106

测试点编号 n ≤ n \leq n m ≤ m \leq m k ≤ k \leq k特殊性质
1 ∼ 2 1 \sim 2 12 10 10 10 15 15 15 100 100 100 a i = 0 a _ i = 0 ai=0
3 ∼ 5 3 \sim 5 35 10 10 10 15 15 15 100 100 100
6 ∼ 7 6 \sim 7 67 1 0 4 10 ^ 4 104 2 × 1 0 4 2 \times 10 ^ 4 2×104 1 1 1 a i = 0 a _ i = 0 ai=0
8 ∼ 10 8 \sim 10 810 1 0 4 10 ^ 4 104 2 × 1 0 4 2 \times 10 ^ 4 2×104 1 1 1
11 ∼ 13 11 \sim 13 1113 1 0 4 10 ^ 4 104 2 × 1 0 4 2 \times 10 ^ 4 2×104 100 100 100 a i = 0 a _ i = 0 ai=0
14 ∼ 15 14 \sim 15 1415 1 0 4 10 ^ 4 104 2 × 1 0 4 2 \times 10 ^ 4 2×104 100 100 100 u i ≤ v i u _ i \leq v _ i uivi
16 ∼ 20 16 \sim 20 1620 1 0 4 10 ^ 4 104 2 × 1 0 4 2 \times 10 ^ 4 2×104 100 100 100

就这样了

#include <cstdio>

int main(){
	freopen("bus.in","r",stdin);
	freopen("bus.out","w",stdout);
}

T h e The The E n d End End

后记:

今天 CSP-J 分数线下来了,重庆居然是全国最高!!!

但是分数线居然只有 250。

死里逃生!!!

完美压线 一分不差!!!

果然我人品爆炸!!!

( ̄▽ ̄)~*( ̄▽ ̄)/(* ̄︶ ̄)(ノ ̄▽ ̄)ヽ( ̄▽ ̄)ノ(~ ̄▽ ̄)~ ︿( ̄︶ ̄)︿

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值