普及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.
不会做,还是要多学习