首页 写随笔

cdcq(本博客废弃!现用博客:https://www.cnblogs.com/cdcq/)

本博客废弃!现用博客:https://www.cnblogs.com/cdcq/

导航

【P1379】天才的约数和

来自GDOI2007,原题已不可考……

又自己做出来了好开心,找特殊性是个关键的切入点

原题:

这天周航遇到了靳泽旭。
   周航:“我是天才!”
   靳泽旭:“你为什么是天才?”
   周航:“你随便告诉我一个数字,我立即可以算出它所有约数之和,以及所有约数的倒数和!”
   靳泽旭:“换过来,我告诉你一个数的所有约数(包括1和该数本身)的和以及约数的倒数之和,你是天才你应该立即能推出这个数是什么!”
   周航被难倒了!
   现在,这个难倒了天才的题目就交到你手上了。

 

很像数论对吧

反正我没用数论知识

手玩小数据,玩到8的时候就可以发现一个很明显的规律:(不会搞表达式只能鼠绘一。一

把分母搞成一样的(通分)以后,分子就是所有约数和,分母是这个数,题目中也给出了约数和

分子上的约数和可能会和分母约掉,那么把分子和分母还原成约分之前的样子(分子分母同时*给出的约数和/分子)

如果给出的约数和%分子!=0,根据显然法可得,显然,无解

然后还需要验证一下,如果还原后的分母的约数和等于给出的约数和,还原后的分母就是答案

可以打表证明对于任意一组数据要么无解要么一组解,数学证明我不会(逃

在赛场上真不会也可以赌一下

然后搞一搞就行了,代码很好写

找特殊性是切入点,打表大法好

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 using namespace std;
 7 long long read(){long long z=0,mark=1;  char ch=getchar();
 8     while(ch<'0'||ch>'9'){if(ch=='-')mark=-1;  ch=getchar();}
 9     while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
10     return z*mark;
11 }
12 long long a,b,c;
13 long long jie(long long x){
14     int _q=int(sqrt(x*1.0));
15     long long bowl=0;
16     for(int i=1;i<=_q;i++)if(!(x%i))  bowl+=i+x/i;
17     if(_q*_q==x)  bowl-=_q;
18     return bowl;
19 }
20 int main(){//freopen("ddd.in","r",stdin);
21     for(;;){//徐王大法好
22         a=read(),b=read(),c=read();
23         if(!a && !b && !c)  break;
24         if(a%b){  printf("0\n");  continue;}
25         c*=a/b;
26         if(a!=jie(c))  printf("0\n");
27         else  printf("1 %lld\n",c);
28     }
29     return 0;
30 }
View Code

 

posted on 2016-11-10 16:31  cdcq_old  阅读(280)  评论(0编辑  收藏  举报