题目描述
把一个正整数分成一列连续的正整数之和。这个数列必须包含至少两个正整数。你需要求出这个数列的最小长度。如果这个数列不存在则输出-1。
输入
每行包含一个正整数n。
每个文件包含多行,读入直到文件结束。
输出
对于每个n,输出一行,为这个数列的最小长度。
样例输入
9
2
样例输出
2
-1
数据范围
对于所有数据,n≤263。
思路
这题我们发现,数据十分的大,可以找找规律。
那么还剩下不是2的次方的偶数。这一部分,我们选择暴力
我们暴力枚举答案,O(1)时间计算出等差序列的首项和末项,在求出等差序列总和,判断是否与N相等,若相等,输出;不相等,继续枚举
#include
#define rg register
using namespace std;
long long n,st,en,er[65];
bool bj;
long long sigma(long long x,long long y)
{
if ((x+y)%2==0) return (x+y)/2*(y-x+1);
else return (y-x+1)/2*(x+y);
}
int main()
{
er[0]=1;
for (rg int i=1;i<=63;i++)
er[i]=er[i-1]<<1;
while (scanf("%lld",&n)==true)
{
bj=false;
if (n&1) printf("2\n");
else
{
for (rg int i=0;i<=63;i++)
{
if (er[i]>=n)
{
if (er[i]==n) bj=true;
break;
}
}
if (bj) printf("-1\n");
else
{
for (rg int i=3;;i++)
{
if (i&1)
{
st=n/i-(i>>1);
en=n/i+(i>>1);
if (sigma(st,en)==n)
{
printf("%d\n",i);
break;
}
}
else
{
st=n/i-(i>>1)+1;
en=n/i+(i>>1);
if (sigma(st,en)==n)
{
printf("%d\n",i);
break;
}
}
}
}
}
}
return 0;
}
题目描述
在这个问题中,给定一个值S和一棵树。在树的每个节点有一个正整数,问有多少条路径的节点总和达到S。路径中节点的深度必须是升序的。假设节点1是根节点,根的深度是0,它的儿子节点的深度为1。路径不必一定从根节点开始。
输入
第一行是两个整数N和S,其中N是树的节点数。
第二行是N个正整数,第i个整数表示节点i的正整数。
接下来的N-1行每行是2个整数x和y,表示y是x的儿子。
输出
输出路径节点总和为S的路径数量。
样例输入
3 3
1 2 3
1 2
1 3
样例输出
2
数据范围
对于30%数据,N≤100;
对于60%数据,N≤1000;
对于100%数据,N≤100000,所有权值以及S都不超过1000。
思路
从每个点暴力DFS,如果当前值加上他的儿子的值是否小于S,如果小于,就DFS(儿子),每次当前值等于S时,答案+1
#include
#define rg register
using namespace std;
int n,m,x,y,ans,tot,c[100005];
struct note
{
int head,next,to;
}a[100005];
void add(int x,int y)
{
tot++;
a[tot].to=y;
a[tot].next=a[x].head;
a[x].head=tot;
}
void dfs(int now,int s)
{
if (s==m) ans++;
for (rg int i=a[now].head;i;i=a[i].next)
{
int v=a[i].to;
if (s+c[v]<=m) dfs(v,s+c[v]);
}
}
int main()
{
scanf("%d%d",&n,&m);
for (rg int i=1;i<=n;i++)
scanf("%d",&c[i]);
for (rg int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
}
for (rg int i=1;i<=n;i++)
dfs(i,c[i]);
printf("%d\n",ans);
return 0;
}
题目描述
生活可以很简单。可以探索水底世界的神秘,也可以去发现奇特新生物,亦或踏上一段新生的旅程。在必须要迎接挑战或跟周围的生物进行生存争夺之前,享受自由的飞翔。此时你会觉得生活是如此美好。
像蛇喜欢吃浮游生物一样(哦,我好像忘记告诉你这个常识),每天,你可以吃一些你周围的基础生物,然后会在你的尾巴上得到一个能量圈。你将会有好多种不同的能量圈,每一个都会被赋予一个能量。你可以拥有多个同种的能量圈,但是对于新得到的能量圈,它的能量不能大于你已拥有的任何一个能量圈。在前面规则的前提下,获得新的能量圈的种类的概率是一样的。一天天过去,你得到越来越多的能量,开始了进化演变。
但是你也有自己的问题,有时你会面对邪恶的果冻鱼。它会追着你咬你,你不得不扔出最小能量值的能量圈然后赶忙逃跑。在这种情况下,你不会有任何的胃口了,因此这天你将不再得到任何能量圈。幸好,当你没有任何能量圈的时候,果冻鱼就算看见你也不会追着你,此时你可以好好地享用美食。
你听说当你的总的能量值超过了某个阈值之后,可以进化成强大模式并能够吃掉果冻鱼。是时候反击了!下面是本题的问题:预计要过多少天你才能进化成强大模式?(第一天默认你没有任何能量圈)
输入
输入包含多个测例。对每个测例会有两行。第一行是一个浮点数P,一个整数T和一个整数N。P是每天遇到果冻鱼的概率,T是阈值。第二行是N个不同的正整数,表示每一种能量圈的能量值。
输出
对于每个测例,输出一行表示预计要过多少天你的能量值能够超过阈值,四舍五入到三位小数。
样例输入
0.5 0 1
1
0.5 1 2
1 2
样例输出
1.000
2.000
数据范围
对于所有数据,0.1≤P≤0.9,1≤T≤50,1≤N≤30。
题目描述
有人问现实中为什么总是男生追求女生,反过来很少。实际上女生也是想主动追求男生的,但是世俗中对于主动追求男生的女生有种歧视,这样就使得女生不大敢主动追求男生。但是面对喜欢的男生,难道就不出手么?女生只能步步为营,挖坑来引诱男生往里跳。这时候问题就来了,挖掘机技术到底哪家强?
被热血沸腾的广告洗脑了若干天后,Matt终于下定决心,毅然登上了开往泉城的列车,决心寻找生活的希望。
来到布鲁谢特学院后,Matt逐渐地了解了各种型号的挖掘机。在这里我们可以认为有大挖掘机和小挖掘机两种。
今天Matt的任务很简单:首先他要用大挖掘机挖出恰好N单位体积的砂土。由于小挖掘机比较笨拙,它每次挖的砂土体积是固定的。也就是说,设每次挖x单位体积砂土,那么N需要被x整除。在挖出若干堆体积为x的砂土后,Matt需要计算x的“难挖指数”。体积x的“难挖指数”定义如下:对于某个不超过x的体积y,如果x与y的最大公约数为1,那我们认为体积y是“难挖的”,x的“难挖指数”就要加上y。
由于Matt之后还需要用小挖掘机处理被大挖掘机挖出的砂土,他希望知道所有可能的x的难挖指数的和,这样他好估算今天要干多久,不然作为布鲁谢特的高才生,他出门要被笑话的。
输入
第一行一个整数T,表示数据组数。
接下来T行每行一个整数表示N。
输出
对于每个数据输出一行一个整数表示难挖指数的和。
样例输入
3
2
3
4
样例输出
2
4
6
数据范围
对于30%的数据有T<=20,N<=10^4。
对于60%的数据有T<=100,N<=10^7。
对于100%的数据有1<=T<=1000,1<=N<=10^9。
思路
先把题目简单说眀,对于每个N,他的难挖指数为他的因子x的难挖指数的和,而x的难挖指数为从1~x中和x互质的y的总和。
那么我们先对x分析,我们知道如果a和b互质,那么a和a-b也互质(a>b),那么很显然的,x的难挖指数就为x*个数/2。
为什么呢,请看:
设x=5
与5互质的数分别是1、2、3、4,让1和4配对,2和3配对,就可以配出两个5,和就为10
现在的问题就是,个数怎么求以及x怎么快速得出
要求个数,其实就是求欧拉函数,利用欧拉函数的通向公式phi(x)=x *(1-1/p1) * (1-1/p2) * …… * (1-1/pn),p1、p2……pn都是x的质因数
那么x怎么快速得出呢?
我们可以将n分解质因数,然后再组成x就好了
#include
#include
#define rg register
#define N 100000
using namespace std;
int t,n,num;
long long ans,x,ol,p[N],c[N],cf[N];
bool b[N];
void js(int now)
{
if (now>p[0])
{
ans+=(x*ol)/2;
if (x==1) ans++;
return;
}
js(now+1);
long long save=x,zj=p[now]-1;
for (rg int i=1;i<=cf[now];i++)
{
ol*=zj;
x*=p[now];
js(now+1);
ol/=zj;
zj*=p[now];
}
x=save;
}
int main()
{
memset(b,true,sizeof(b));
b[1]=false;
for (rg int i=2;i<=N;i++)
for (rg int j=2;j<=N/i;j++)
b[i*j]=false;
num=0;
for (rg int i=1;i<=N;i++)
{
if (b[i])
{
num++;
c[num]=i;
}
}
scanf("%d",&t);
while (t--)
{
ans=0;
x=1;
ol=1;
memset(p,0,sizeof(p));
memset(cf,0,sizeof(cf));
scanf("%d",&n);
for (rg int i=1;i<=num;i++)
{
if (n%c[i]==0)
{
p[++p[0]]=c[i];
while (n%c[i]==0)
{
cf[p[0]]++;
n/=c[i];
}
}
}
if (n>1)
{
p[++p[0]]=n;
cf[p[0]]=1;
}
js(1);
printf("%lld\n",ans);
}
return 0;
}