2020.02.07普及C组模拟赛4

普及C组模拟赛4

**1.权势二进制 **

题目描述

一个十进制整数被叫做权势二进制,当他的十进制表示的时候只由0或1组成。例如0,1,101,110011都是权势二进制而2,12,900不是。
当给定一个n的时候,计算一下最少要多少个权势二进制相加才能得到n。

输入

k组测试数据。
第1行给出一个整数k (1<=k<=10)
第2到k+1行每行一个整数n(1<=n<=1000000)

输出

输出答案占k行。
每行为每个n的答案。

样例输入

1
9

样例输出

9

正解
这题找出各个位数的最大值
例如:10009,答案是9
例如:14532,答案是5
因为10001+1+1+1+1+1+1+1+1=10009, 9个权势二进制
因为11111+01111+01110+01100+00100=14532,5个权势二进制
AC代码

#include<iostream>
#include<cstdio>
using namespace std;
long long k,n,s;
int main()
{
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
	cin>>k;//位数
	for(int i=1;i<=k;i++)
	{
		cin>>n;
		s=0;
		while(n!=0)//查看每一位,找最大的数字
		{
			s=max(s,n%10);
			n/=10;
		}		
		cout<<s<<endl;
	}
	return 0;
}

2.num

题目描述

   KC邀请他的两个小弟K和C玩起了数字游戏。游戏是K和C轮流操作进行的,K为先手。KC会先给定一个数字Q,每次操作玩家必须写出当前数字的一个因数来代替当前数字,但是这个因数不能是1和它本身。例如当前数字为6,那么可以用2,3来代替,但是1和6就不行。现在规定第一个没有数字可以写出的玩家为胜者。K在已知Q的情况,想知道自己作为先手能不能胜利,若能胜利,那么第一次写出的可以制胜的最小数字是多少呢?整个游戏过程我们认为K和C用的都是最优策略。

输入

只包括一个正整数Q

输出

第一行是1或2,1表示K能胜利,2表示C能胜利。
若K能胜利,则在第二行输出第一次写出的可以制胜的最小数字,若是第一次就无法写出数字,则认为第一次写出的可以制胜的最小数字为0。
说明:若C能胜利,不用输出第二行,输出2即可。

样例输入

6

样例输出

2

数据范围限制

对于30%的数据,Q<=50; 对于100%的数据,Q<=10^13。

正解
有三种情况
1.是个质数,则K胜利
2.是两个质数的积,则C必胜
3.是多个质数的积,则K胜利,输出最小两个质数的积

分解质因数
AC代码

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
long long q,j,o,num;
int main()
{
	freopen("num.in","r",stdin);
	freopen("num.out","w",stdout);
	cin>>q;
	j=q;
	for(int i=2;i<=sqrt(q);i++)//分解质因数
	{
		if(j%i==0&&num==0)o=i;
		while(j%i==0)
		{
			num++;
			j/=i;
			if(num==2){cout<<1<<endl<<o*i;break;}//多个质数的积	
		} 
		if(num>=2)break;
	}
	if(num==0)cout<<1<<endl<<0;//是个质数
	if(num==1)cout<<2;//两个质数的积
	return 0;
}

3.复仇者vsX战警之训练(train)

题目描述

月球上反凤凰装甲在凤凰之力附身霍普之前,将凤凰之力打成五份,分别附身在X战警五大战力上面辐射眼、白皇后、钢力士、秘客和纳摩上(好尴尬,汗)。
在凤凰五使徒的至高的力量的威胁下,复仇者被迫逃到昆仑的一座山上,因为凤凰五使徒监视不到那里。
霍普加入了复仇者,为了磨练自己,她在n个山峰之间跳跃。
这n个山峰在一条直线上,每个山峰都有不同的高度,只知道这些山峰在水平上相对位置。霍普可以将这些山峰左右移动但不能改变他们的相对位置(要保证两两山峰间距为整数且大于等于1)。霍普要从最矮的山峰开始跳,每次跳向第一个比现在她所在的山峰高的山峰,一共跳n-1次,由于能力有限,每次跳跃的水平距离小于等于d。
霍普想知道如何移动这些山峰,使得在可以经过所有的山峰并跳到最高的山峰上的基础下,又要使最矮的山峰和最高的山峰的水平距离最远,霍普要你求出最远的水平距离。如果无论如何也不能经过所有的山峰并跳到最高的山峰上,那么输出-1。

输入

输入文件名为attack.in。
本题每个测试点有多组数据,
在第一行中有一个整数t,表示数据的数目(t<=500)
对于每组数据:
第一行包含两个整数n(1≤n≤1000)和d(1≤d≤1000000)。
下一行包含n个整数,给出n个山峰的高度,输入顺序即为山峰在水平上的相对顺序。在每个数据中,所有的高度都是唯一的。

输出

输出文件名为attack.out。
输出共t行。
对于每组数据输出最远的水平距离。如果无论如何也不能经过所有的山峰并跳到最高的山峰上,那么输出-1。

样例输入

3
4 4
20 30 10 40
5 6
20 34 54 10 15
4 2
10 20 16 13

样例输出

3
3
-1

数据范围限制

【数据说明】
对于100%的数据,1≤n≤1000,1≤d≤1000000

正解
最短路,对于最高的在最低的右边,那么单向图的边权为D的边就是从右往左的。单向图中的每一个点与他相邻的点的边权为-1,并是从左往右的。而对于最高的在最低的左边的则反之。打个SPFA就可以了。
AC代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int t,n,d,tot,dis[1005],v[1005],b[1005],head,tail,hd[1000005],p[1000005];
struct stu
{
	int to,next,w;
}c[1000005];
struct stu2
{
	int h,num;
}a[1005];
bool cmp(stu2 x,stu2 y)
{
	return x.h<y.h;
}
void add(int x,int y,int z)//邻接表
{
	tot++;
	c[tot].to=y;
	c[tot].next=hd[x];
	hd[x]=tot;
	c[tot].w=z;
}
void spfa(int x)//spfa模板
{
	memset(dis,127,sizeof(dis));
	memset(v,0,sizeof(v));
	memset(b,0,sizeof(b));
	p[1]=x;
	dis[x]=0;
	v[x]=1;
	head=0;tail=1;
	while(head<tail)
	{
		head++;
		int y=p[head];
		for(int i=hd[y];i;i=c[i].next)
		 if(dis[y]+c[i].w<dis[c[i].to])
		  {
		  	dis[c[i].to]=dis[y]+c[i].w;
		  	if(v[c[i].to]==0)
		  	{
		  		b[c[i].to]++;
		  		v[c[i].to]=1;
		  		p[++tail]=c[i].to;
		  		if(b[c[i].to]>n){dis[a[n].num]=dis[a[1].num]=-1;return;}//小心有环
			}
		  }
		v[y]=0;  
	}
}
int main()
{
	freopen("attack.in","r",stdin);
	freopen("attack.out","w",stdout);
	cin>>t;
	for(int i=1;i<=t;i++)
	{
		memset(hd,0,sizeof(hd));
		tot=0;
		cin>>n>>d;
		for(int j=1;j<=n;j++)
		{
			cin>>a[j].h;
			a[j].num=j;
			if(j>=2)add(j,j-1,-1);//-1的路
		}
		sort(a+1,a+1+n,cmp);
		for(int j=2;j<=n;j++)
		{
			if(a[j-1].num<a[j].num)add(a[j-1].num,a[j].num,d);
			else add(a[j].num,a[j-1].num,d);
		}
		if(a[1].num<a[n].num)//看谁最低和最高的山,谁先输入,就从谁开始,到另一个点
		{	
			spfa(a[1].num);
			cout<<dis[a[n].num]<<endl;
		}
		else
		{
			spfa(a[n].num);
			cout<<dis[a[1].num]<<endl;
		}
	}
	return 0;
}

4.第四题

题目描述

Background (保证没有题意)
“命运的线索正在汇聚,故事的结局正在浮现。但这个结局不是你所喜欢的,就像你不喜欢那个少侠和小侠女抱憾终生的故事,你还想改写它么?”路鸣泽说。
“命运……么?路明非轻声说着,回望那凝滞的战斗场面。 红色的长发在雨中舞动,滴落在刀锋上碎裂,那张漂亮倔强的脸上带着一丝凶猛狰狞,诺诺像是一只下山的母老虎。 可如果命运已经注定呢?就像布加迪威龙跑得再快也跑不过时光。无论你咆哮或嘶吼,血战百番,最终还是会被命运的丝线牵引,死在这场无边的暴风雨里。
“让昆古尼尔射出,却又不让它命中,对么?”
“不愧是我的哥哥,立刻就明白了这游戏的本质,我们不妨称之为‘欺骗死神’。”路鸣泽微笑,“但要抓紧时间哦,如果你不能在梦境中改变故事的结局,一旦奥丁进入现实世界,就什么都来不及了。当它在现实中投出那支矛的时候,诺诺将再无逃生之地。”
“奥丁的能力……难道是梦境?它是龙王么?”路明非恍然大悟。
“不,梦境这种高大上的能力怎么是奥丁能拥有的?”路明泽诡秘地微笑,“我的能力才是梦境!”

Description
“尼伯龙根是一棵由n-1条高架路连起n 个地区的树,每一次Load,你都会重生在某一个地区。如果重生点是整个尼伯龙根的重心,也就是这个树的重心,那么你就能在最短时间内带诺诺逃脱啦。”
“对了,再给你一点方便咯,你可以选一条高架桥断掉,再连接另外两个地方,每次Load只能用一次技能,而又必须使整个它仍构成树形结构。你的Save点在这里,Load自然会恢复原始的尼伯龙根咯。”

(以下没有题意)
读档
路明非还想问什么,但整个世界微微颤动起来,好像即将从梦中醒来。悬浮的雨滴摇摇欲坠,长发的发梢轻轻摆动,枪火慢慢地膨胀,死寂中传来悠长而沉雄的马嘶声。
“游戏关卡‘昆古尼尔之光’,第1次LOAD,哥哥,努力奋斗啊,当个命运的贼,从死神的手里,把你心爱的女孩……偷出来!” 路明泽的声音渐渐模糊在雨中。

输入

第一行两个整数n,m,n意义如题,m表示路明非Load了m次。
接下来n-1行,每行两个整数x,y表示节点x,y之间存在一条边。
接下来m行,每行一个整数p,表示这次Load的重生地区。

输出

对于每一个询问,输出一行
如果可以则输出”YES”,否则输出”NO”(注意没有引号)

样例输入

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

样例输出

YES
NO
NO

数据范围限制

对于20%的数据 1<=n,m<=50
对于50%的数据 1<=n,m<=3000
对于100%的数据 1<=n,m<=200000

提示

树的重心是指树上的某一个(也有可能有两个)点,如果以这个点为根,那么它的子树的大小(所含点数)的最大值在整棵树中是最小的。

正解
还不会
AC代码

待更新

赛后总结

1.
考试时想到正解,AC
2.
直接AC
3.
还是不懂分析,这方面有点欠缺,最后才AC
4.
不会做,还是要多学习

谢谢观看

发布了52 篇原创文章 · 获赞 80 · 访问量 1719

猜你喜欢

转载自blog.csdn.net/weixin_45524309/article/details/104505536