吉首大学第十届“新星杯”大学生程序设计大赛(暨新生网络同步赛)

吉首大学第十届“新星杯”大学生程序设计大赛(暨新生网络同步赛)

链接:http://jsuacm.cn/contest.php

——————————————————————————————
笔记:就过了三题(Problem E 会长的榜单,Problem J 会长数,Problem L 馋嘴会长逛小吃街)

问题 A: 学习快速幂

描述

众所周知,快速幂是一个很重要的算法,相比朴素算法,可以更加快速的求解形如(ab)%c的问题(ab意思是a的b次幂),此算法的时间复杂度是log级别的。
现在相信你已经会快速幂算法了,今天你的同学zcb来问你他这段快速幂代码是不是正确的,他的快速幂写的是递归形式的,虽然之前你没学过,但是看了两眼还是立马发现了问题所在。程序运行是正确没错,但是有个地方没有优化,导致时间复杂度并不能过关。
如下,给你这段快速幂代码,为了证明zcb的代码有问题,请你算出他的代码的复杂度以证明zcb的递归有问题。为了更加有说服力,给你一个数n,你需要算出此代码在计算a0,a1,a2…an,的复杂度的和。因为显然a与本题复杂度计算无关,所以并不给出a的值。

在这里插入图片描述

图中11,12行的注释代码为你认为的正确写法,不过与本题并无关系,在这题中,我们定义在递归结束后count的值为一次求快速幂的复杂度,比如计算a0,a1,a^2分别需要0,1,3的复杂度。

#格式

输入格式

首先输入一个t,代表有t组输入(1<=t<=1e5)
接着每组输入给你一个数n(0<=n<=1e9)
本题请使用scanf printf输入输出

输出格式

对于每组输入,你需要算出此代码在计算a0,a1,a2…an,的复杂度的和。

样例

样例输入

3
0
1
2

样例输出

0
1
4

提示

笔记:这题没做出来

正确代码:

在这里插入代码片

——————————————————————

问题 B: 算数之王

描述

给你一堆随机的卡牌,从中取出两组卡牌(不能重复取),要求这两组的卡牌点数之和相等,请问有多少种取法,在所有的取法中每组最大的点数为多少,每组点数和相同视为同一种方案。为了方便,卡牌点数统一用1-13(A-K)的数字表示。

格式

输入格式

第一行输入一个整数T,代表测试数据组数(1<=T<=100)
每组数据分成两行,第一行输入正整数n(n<=10)为卡牌张数,第二行为每张卡牌的点数。

输出格式

共一行,输出方案数和所有合法方案中最大每组点数之和(以空格分开)。没有合法取法,则输出0 0。
注意是0 0

样例

样例输入

1
6
1 3 4 2 3 5

样例输出

7 9

提示

1)1 2 和 3
2)1 3 和 4
3)1 4 和 5
4)1 5 和 2 4或
3 3 和 2 4或
3 3 和 1 5
5)2 5 和 3 4
6)1 3 4 和 3 5
7)1 2 3 3 和 4 5
共7种方案,所有合法方案中,最大每组点数和为9

笔记:

正确代码:

在这里插入代码片

——————————————————————

问题 C: LeeLdler的数字

描述

有一天LeeLdler偶然发现一个规律

像这种形如(n3+a3 )/(n3+b3)=(n+a)/(n+b)有很多种
现在LeeLdler给出一个数字n,请找出任意一对不相等的正整数a,b满足上述等式.

格式

输入格式

输入一个正整数n(3<=n<=10^9)

输出格式

输出两个正整数a,b,以空格隔开. a!=b,且a,b都在int范围内.
答案可能存在多组,输出任一组即可

样例

样例输入

5

样例输出

2 3

笔记:

正确代码:

在这里插入代码片

——————————————————————

问题 D: 珍爱生命,远离赌博

描述

zqc和lbg是实验室的两个赌徒,有一天他们把钱都输给了prz之后就想起了用牌来玩一个小游戏来练练自己的牌技。zqc先抽一张牌,亮出在桌面上,然后lbg抽一张牌放在上一张牌后面,依此放牌,如果放的这张牌和之前的某张牌点数相同则可以取走这两张相同点数牌以及他们之间的牌(A到K牌的分数为1到12),牌的大小顺序:A<2<3<4<5<6<7<8<9<J<Q<K,没有大小王。请你求出谁赢了,并且输出赢的人的分数。最终桌上剩下的牌忽略不计,如果最终两人分数相同则输出-1。两人的分数即他们整个过程取走的牌的分数之和。

格式

输入格式

输入一个字符串s(字符串不为空且长度最长不超过2e6),表示他们完整放牌的过程。

输出格式

输出一行,赢的人和赢的人的分数。

样例

样例输入

A23456789JQK4A

样例输出

zqc 76

笔记:模拟超时

正确代码:

在这里插入代码片

————————————————————————

问题 E: 会长的榜单

描述

众所周知,每场ACM比赛都有排名榜单,上面会显示每个队的过的题和过题时间,每次给20级的新生们上机辅导的时候会长都会坐在讲台上看榜单,其实会长看到的榜单和大家看到的是不一样的,正常的榜单的过题时间是小时加分钟(比如:XX:XX:XX,或者看图),而会长看到的过题时间是以秒为单位的(比如正常榜单的01:00:00,会长看到的是3600)。这次新星杯网络赛会长还是会一如既往的坐在讲台上看榜单,但是会长最近由于期末周复习,脑子用太多了,换算不过来了,聪明的你能帮帮会长吗?

格式

输入格式

输入两行
第一行一个整数 n 代表本场题目数量(1<=n<=10)
第二行一个字符串代表某一位选手的榜,格式为选手昵称(不超过10个字符)和各个题目的过题时间;
如果这题没通过,时间显示为0(众所周知不可能有人0s过题)
一场ACM比赛时间为5小时

输出格式

输出一行表示这位选手的榜换算成正常显示时间的榜单,(未通过的题目依旧显示0即可)

样例

样例输入

10
顺十字 3600 3660 7200 300 0 1500 2600 4561 2345 8945

样例输出 Copy

顺十字 01:00:00 01:01:00 02:00:00 00:05:00 0 00:25:00 00:43:20 01:16:01 00:39:05 02:29:05

笔记:

正确代码:

#include<iostream>
#include<cmath>
#include<vector>
#include<stdio.h>
using namespace std;

int main(){
	int n;
	while(cin>>n){
		string name;
		cin>>name;
		cout<<name<<" ";
		int time;
		for(int i=0;i<n;i++){
			if(i) cout<<" ";
			cin>>time;
			int s,f,m;
			if(time==0){
				cout<<"0";
			}
			else{
				s=time/3600;
				f=time/60%60;
				m=time%60;
				if(s<10){
					cout<<"0"<<s<<":";
				}
				else{
					cout<<s<<":";
				}
				if(f<10){
					cout<<"0"<<f<<":";
				}
				else{
					cout<<f<<":";
				}
				if(m<10){
					cout<<"0"<<m;
				}
				else{
					cout<<m;
				}	
			}
			
			
		}
		cout<<endl;
	}
	return 0;
} 

————————————————————————

问题 F: 寝室争“爸”赛

描述

谁是寝室的爸爸?
一个爸爸和五个儿子的故事每天都在上演,可是到底谁才是那个爸爸呢?
现在我们一起来玩一个游戏,赢的人就是爸爸。
为了使游戏简单,我们就不考虑6个人的情况了。现在就只考虑2个人的情况。也就是说,这两个人玩游戏,谁赢了,谁就是那个爸爸。
在这里插入图片描述

游戏规则如下:
cxy获得了一个2到n的序列,现在他有个能力可以通过抽取x个数,从而覆盖所有未被抽取的2-n中的数;
覆盖的定义是:假如抽取了y,则y的整数倍都可被覆盖,y的所有因子也都可被覆盖。
被覆盖的数也还可以被继续抽取。 现在他想抽取的x个数来覆盖2-n的序列并且x个数的和是所有可能的情况最小的;
总之,cxy将抽取x个数,来达到其他所有未抽取的数都被至少覆盖一次的目的,并且抽取的x个数的和要是最小的。
x为任意个数

举个例子:如果n是6,则cxy的序列为:2 3 4 5 6;
如果cxy抽取的是序列是:3 4 5 6 就可以把2-6全都覆盖,因为2是4的因子,4可以把2覆盖;
如果cxy抽取的是序列是:2 3 5 就可以把2-6全都覆盖,因为4和6都是2的倍数,所以2可以把4和6覆盖;
如果cxy抽取的是序列是:4 5 6 就可以把2-6全都覆盖,因为2和3都是6的因子,所以6可以把2和3覆盖;
上面三种抽取方法都是满足条件的抽取。但是上面第二种的抽取方法的(2+3+5=10)和是最小的,所以合法的抽取是上面第二种抽取方法。
即n=6时,抽取的序列为2 3 5

现在yls和cxy开始比赛,二人轮流在cxy抽取的序列中选择一个数拿出来,
最后所有的数都拿完的情况下,
如果yls所拿数的和是偶数,cxy所拿数的和是奇数,则yls胜利;
如果cxy所拿的数的和是偶数,yls所拿的数的和是奇数,则cxy胜利;
如果cxy所拿的数的和是偶数,yls所拿的数的和是偶数,则和大者胜利;
如果cxy所拿的数的和是偶数,yls所拿的数的和是偶数,且两者和相等,则无人胜利,输出-1;
如果cxy所拿的数的和是奇数,yls所拿的数的和是奇数,则无人胜利,输入-1;
cxy先手,保证yls和cxy都足够聪明,能做出最利于自己的选择;
如果有一方已经一定赢不了,那她应尽力避免另外一方胜利。达到平局。
请输入胜利一方的名字,如果都胜利不了,则输入-1

格式

输入格式

输入T表示T组数据 (1<=T<=30)
接下来T行,每行输入一个n (3<=n<=1000000)

输出格式

请输入胜利一方的名字,如果都胜利不了,则输出-1

样例

样例输入

2
3
4

样例输出

cxy
cxy

笔记:

正确代码:

在这里插入代码片

————————————————————————

问题 G: Substr and Subset

描述

给出n个由小写字母组成的串si,q组询问每次询问首先输出k,m两个数,然后跟随 k 行,每行两个数 ai,bi,表示选取第 ai个串长度为 bi 的前缀放入集合 v,问把集合v中的所有串分割成不同的 m 个非空集合,且使这些集合里的串不存在某一个串是另一个串的后缀有多少种方案。

格式

输入格式

第一行给出两个数 n , q ,分别代表串数和询问数。
接下来 n 行,每行包含一个字符串
接下来 q 组询问,每组询问第一行输入 k,m 两个数,接下来跟随 k 行
每行有两个数 a,b,表示选取第 ai 个串长度为 bi 的前缀放入集合 v

对于所有数据1≤n,q≤105,∑∣si∣≤105,∑k≤10^5,m≤min(k,300)
保证输入的a,b合法

输出格式

每行输出一个数表示答案对 109+7 取模后的结果

样例

样例输入

2 3
aabaa
aabaa
4 3
1 2
1 3
1 4
2 5
4 2
2 2
1 3
2 4
1 5
2 2
1 1
1 1

样例输出 Copy

5
4
1

提示

对于第一组样例的第一次询问的解释:
询问中选择了四个前缀,分别为

第一个串的长度为 2 的前缀:aa

第一个串的长度为 3 的前缀:aab

第一个串的长度为 4 的前缀:aaba

第二个串的长度为 5 的前缀:aabaa

显而易见的,第一个前缀是第四个前缀的后缀,所以这两个串不能放在同一个集合里。所以所有的可能情况有:

{aa},{aabaa},{aab,aaba}

{aa,aab},{aabaa},{aaba}

{aa,aaba},{aabaa},{aab}

{aa},{aabaa,aab},{aaba}

{aa},{aabaa,aaba},{aab}

一共五种。

笔记:

正确代码:

在这里插入代码片

————————————————————————

问题 H: 圣诞糖果

描述

     传说每到12月24日晚上,有个神秘人会乘驾由9只驯鹿拉的雪橇在天上飞翔,挨家挨户地从烟囱进入屋里,然后偷偷把礼物放在孩子床头的袜子里,或者堆在壁炉旁的圣诞树下。他在一年中的其他时间里,都是忙于制作礼物和监督孩子们的行为。
     由于今年疫情的原因,圣诞老人耽搁了制作礼物的时间,在圣诞节到来之前将无法完成礼物的制作。圣诞老人只好去集市买一些圣诞糖果来加速圣诞礼物的制作。卖圣诞糖果的老板有一个独特的卖法,有n堆糖果围成一个圈,第i堆糖果的数量为a[i]。第i堆糖果和第i+1堆糖果相连,第n堆糖果和第1堆糖果相连。圣诞老人只能选择任意一段连续的糖果进行购买,所需要支付的金额是那连续的一段糖果堆中,数量最多的糖果与数量最少的糖果的差值。例如,圣诞老人选的连续糖果堆的里含糖果的数量分别是: 9 3 2 7 11,则数量最多的糖果数是11个,数量最少的糖果数量为2个,所以圣诞老人需要支付11-2=9个金币。现在圣诞老人至少需要m个糖果才能完成圣诞礼物的制作,但又忙于回家制作礼物,所以圣诞老人只购买一次,你能否帮圣诞老人算一下至少需要支付多少个金币才能在一次购买中购买到不少于m个糖果。如果圣诞老人无法购买到m个糖果,则输出-1。

格式

输入格式

第一行输入一个t(1<=t<=10),代表有t组测试数据
每组测试先输入两个正整数n(1<=n<=1e6),m(1<=m<=1e12),代表有n堆糖果,圣诞老人至少需要m个糖果。(保证t组n加起来不超过1e6)
接下来输入n个整数ai,代表第i堆糖果的数量。

输出格式

如果圣诞老人能购买到不少于m颗糖果,则输出需要支付的最少金币。
否则输出-1。

样例

样例输入 Copy

3
6 18
10 8 3 1 7 9
5 10
8 9 10 11 12
5 50
4 7 5 6 9

样例输出 Copy

1
0
-1

提示

第一个样例:因为所有的糖果堆是围成一个圈,第一堆糖果和最后一堆糖果是相连的。所以选第一堆和最后一堆即可。
第二个样例:选第三堆数量为10的糖果堆,糖果数量最多和最少都是10,所以需要支付的金额为10-10=0。
第三个样例:所有的5堆糖果数加起来都不足50,所以输出-1。

笔记:

正确代码:

在这里插入代码片

————————————————————————

问题 I: 广告(天梯打钱)

描述

团体程序设计天梯赛是中国高校计算机大赛的竞赛版块之一,其规则为10人为1队,竞赛题目分 3 个梯级:基础级设 8 道题,其中 5 分、10 分、15 分、20 分的题各 2 道,满分为 100 分;进阶级设 4 道题,每道题 25 分,满分为 100 分;登顶级设 3 道题,每道题 30 分,满分为 90 分,共15道题。参赛队员可以在比赛中的任何时刻尝试解决任何梯级的题目。但只有当一支队伍的基础题总分大于等于 800 分时,其本队进阶部分的题目分数才被判为有效。只有当其进阶题总分大于等于 400 分时,其本队登顶部分的题目分数才被判为有效。现给出n支队伍的比赛情况,要求你给n支队伍按照有效分数从高到低排好序,如果分数相同则按照队伍ID的升序输出,并且最后一行输出n支队伍中的最高分和所有优胜者(分数最高者,个人分数不受团队影响)的ID(按照ID的升序)
(队员计分根据过题的数据比例计算,也就是说不一定都是0分和满分)

格式

输入格式

第一行输入一个数字n(1<=n<=100),之后11*n行分别输入每支队伍的ID(长度为1到10),每支队伍队员的ID(长度为1到10)和得分情况(按照基础题到登顶题的顺序输入,题目分值分别为5,5,10,10,15,15,20,20,25,25,25,25,30,30,30),保证队员、队伍ID都不重复。

输出格式

按照题目要求顺序输出队伍ID和3个阶段的分数和有效总分以及排名(分数相同排名相同,例:A,B,C三支队伍总分分别为1500,1500,1000,排名为A:1,B:1,C:3),最后一行输出个人最高分和所有优胜者的ID(按照ID的升序)

样例

样例输入

2
JSU0001
000001 5 5 10 10 15 15 20 20 25 25 25 0 30 0 0
000002 5 5 10 10 15 15 20 20 25 25 0 0 0 0 0
000003 5 5 10 10 15 15 20 20 25 25 15 0 0 0 0
000004 5 5 10 10 15 15 20 20 25 10 0 0 0 0 0
000005 5 5 10 10 15 15 20 20 25 0 25 0 0 0 0
000006 5 5 10 10 15 15 20 20 10 25 25 0 20 0 0
000007 5 5 10 10 15 15 20 20 15 0 25 0 0 0 0
000008 5 5 10 10 15 15 20 20 25 0 25 0 0 0 0
000009 5 5 10 10 15 15 20 20 25 10 25 0 0 0 0
000010 5 5 10 10 15 15 20 20 0 25 25 0 0 0 0
JSU0002
000011 5 5 10 10 15 15 20 20 0 25 25 0 30 30 30
000012 5 5 10 10 15 15 20 20 0 25 25 0 0 0 0
000013 5 5 10 10 15 15 20 20 0 0 0 0 0 0 0
000014 5 5 10 10 15 15 20 20 0 25 0 0 0 0 0
000015 5 5 10 10 15 15 20 20 0 0 25 0 0 0 0
000016 5 5 10 10 15 15 20 20 0 0 25 0 0 0 0
000017 5 5 10 10 15 15 20 20 0 25 0 0 0 0 0
000018 5 5 10 10 15 15 20 20 0 0 0 0 0 0 0
000019 5 5 10 10 15 15 20 20 0 0 25 0 0 0 0
000020 5 5 10 10 15 15 20 20 0 25 0 0 0 0 0

样例输出

JSU0001 1000 535 50 1585 1
JSU0002 1000 250 90 1250 2
240 000011

笔记:

正确代码:

在这里插入代码片

————————————————————————

问题 J: 会长数

描述

会长把一个数本身是一个素数、各个数位上的数都是素数、各个数位上的数的和是素数的数叫做会长数,请输出10到100中的所有会长数。

格式

输入格式

输出格式

第一行先输出10-100中会长数的个数,第二行再按从小到大的顺序输出一个会长数,中间按空格隔开,行末无多余空格

样例

样例输入

样例输出

笔记:

正确代码:

#include<iostream>
#include<cmath>
#include<vector>
#include<stdio.h>
using namespace std;
int sushu(int a){
	int q=sqrt(a);
	if(a<=1) return 0;
	for(int i=2;i<=q;i++){
		if(a%i==0){
			return 0;
		}
	}
	return 1;
}

int gewei(int a){
	int b;
	int f=1;
	int sum=0;
	while(a){
		b=a%10;
		sum+=b;
		if(sushu(b)==0){
			f=0;
		}
		a=a/10;
	}
	if(f==0){
		return 0;
	}
	if(sushu(sum)==0){
		return 0;
	}
	return 1;
}

int main(){
	vector<int>v;
	int ans=0;
	for(int i=10;i<=100;i++){
		if(sushu(i)&&gewei(i)){
			ans++;
			v.push_back(i);
		}
	}
	cout<<ans<<endl;
	for(int i=0;i<ans;i++){
		cout<<v[i]<<endl;
	}
	return 0;
} 

————————————————————————

问题 L: 馋嘴会长逛小吃街

描述

众所周知,会长特别喜欢吃路边小吃,于是会长趁着圣诞夜晚上出完题就骑着小黄车溜到学校外面小吃街去解馋去了,小吃街是一条笔直的大街,我们可以把它抽象成是一条坐标轴,每个小吃摊都位于坐标轴上整数点的位置,而会长可以在坐标轴上的任何一个位置下车开吃,会长虽然爱吃但也很在意自己的身材,所以他只会吃k个小吃摊就回去,于是会长想知道如果自己就停一次车,然后步行去之前想吃的那些小吃摊,最后回到停车的位置,那么最短的步行路程是多少。

格式

输入格式

输入的第一行为一个整数t(1<=t<=100),表示测试样例的组数。
接下来输入t组样例,每组输入占两行,第一行输入两个整数n和k(1<=n<=20,1<=k<=n),n表示想要去吃的小吃摊的位置,k表示会长最多能吃的小吃摊个数;
第二行输入n个整数,表示计划要去的那些小吃摊的位置,位置范围为[0,99]。保证没有多个小吃摊在同一个位置。

输出格式

对于每组输入,输出最短的步行路程。

样例

样例输入

2
4 2
24 13 89 37
6 3
7 30 41 14 39 42

样例输出

22
6

笔记:普通模拟

正确代码:

#include<iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#include<stdio.h>
using namespace std;
 
int main(){
    int t;
    int n,k;
    while(cin>>t){
        while(t--){
            cin>>n>>k;
            int a[n+5];
            for(int i=0;i<n;i++){
                cin>>a[i];
            }
            sort(a,a+n);
            long long sum,minn=2<<15;
            for(int i=0;i<n;i++){
                if(i+k-1<n){
                    sum=(a[i+k-1]-a[i])*2;
                    minn=sum<minn?sum:minn;
                }
            }
             
            cout<<minn<<endl;
        }
    }
    return 0;
} 

————————————————————————

问题 M: 2066年的缩写

描述

在2066年,新型计算机的出现导致算力大增,和40年前 64核 哭睿 i15 的老机器比,运算速度快了不止1000倍(同比个人计算机)。
可因为磁盘和内存的存储原件被垄断,导致价格大增,普通人能用到的存储空间十分有限。因此相比过去市面上出现了各种各样的压缩算法,每个算法适用的情况不同,同时这些算法也良莠不齐。今天你看到了一个二进制压缩算法,他是这样描述的:

对于一段二进制数字(只包含0,1),如果出现了连续的0或1,则我们把这一段连续数量为k的1或0压缩成 数字(二进制表示的k) 形式,并且对于各个已经缩写的段或者不用缩写的段之间用 + 连接。
例如我们把 11111 压缩成 1(101) ,因为有5个1且5的二进制值为 101 ,我们把 000000 压缩成 0(1(10)+0) 因为在这里有6个0,而6的二进制值为110,11又是连续的两个连续的1,所以要缩写成 1(10) ,接着对于 1(10) 和 0 之间我们用 + 连接,所以最后结果是 0(1(10)+0)。

显然这时候你已经发现了,这个算法只适用于有较多连续出现 1 和 0 的情况,现在给你一段只包含0和1的二进制数,请输出他的压缩结果,并且输出这个压缩算法是否有效,我们定义一个压缩有效意味着在其压缩后长度严格小于压缩前的长度,既成功,否则就是失败。
压缩严格按上面的做法执行且不能包含多余的+号,当有连续k个1或0时要把k个数一起压缩,不能左压缩一段1,右压缩一段1,哪怕这样可能会更优。
格式

输入格式

输入第一行包含一个数t,代表需要测试的组数(1<=t<=5)
接着对于每组数据第一行包含一个数n,表示数的长度,1<=n<=1e4
第二行输入一个长度为n的二进制数。可以包含前导0,包含前导0时,前导0也需要参与压缩。

输出格式

对于每组数据
输出第一行表示压缩是否有效,如果有效输出"YES",无效输出"NO"。
第二行输出压缩结果。

样例

样例输入

5
5
11111
6
101111
8
01111111
1
0
22
1111111111000000000010

样例输出

NO
1(101)
NO
10+1(1+0(10))
NO
0+1(1(1(10)))
NO
0
YES
1(1010)+0(1010)+10

提示

样例1:
11111->1(101) 101是5的二进制表示
长度为6,大于原长度5,所以输出NO
样例2:
101111
10不压缩,1111连续于是压缩成1(100)接着00连续于是压缩成0(10)
最后结果为 10+1(1+0(10))
长度为13,大于6输出NO
样例3:
01111111
0不压缩,1111111->1(111)->1(1(11))->1(1(1(10)))
长度为13,大于8,输出NO

笔记:

正确代码:

在这里插入代码片
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值