xdoj 1243 ckj老师爱数学

来源:互联网 发布:易语言砍价源码 编辑:程序博客网 时间:2024/05/01 07:45

题目链接:

xdoj 1243 ckj老师爱数学 传送门

大致题意是已知z,求满足x^2+y^2=z^2的整数解x,y的个数。这道题是在暑期集训结束的组队赛碰到的,原题貌似是BZOJ上求半径为r的圆上整点的个数。

乍一看题,卧槽z的范围怎么那么大,暴力肯定要超时的啊!然后就开始暴力打表找规律= =。。。

想知道正解的话建议去搜BZOJ原题的题解,这里只有我打表找到规律的做法(正解我也不会2333)。

博主首先直接暴力打出了z从1开始到100+左右的表,观察规律。当然这个规律并不算很明显,至少博主是看了很久的。最开始发现,答案为12时的z都是4的倍数+1且为质数,而这些质数的倍数貌似也满足某种规律?然后就实验了很多组数据,首先验证了4的倍数+1且为质数的z的答案都是12。然后以该类数为基础,推断出这些数的倍数与这些数所具有的联系,最后总结出整体的规律。(这种做法真的挺乱搞的,全靠人品、YY和找规律= =)

1、当z为1时,答案为1。

2、z不为1时,将z分解为质因数的幂相乘的形式,p[]数组存质因数,对应的e[]数组存幂次。

若z没有%4余1的质因数,则答案为4,若z含有若干个%4余1的质因数,对于每一个p都有(2*e+1)个4,将所有符合条件(%4余1)的质数的(2*e+1)乘起来,最后所得的结果再乘以4即为答案。(可能表述的不是很清楚,看代码吧)

另外,比赛时分解的时候板子敲错了,但是数据不怎么强,居然过了。当然赛后不久发现了,略一修改成功过了BZOJ原题,想来虽不是正解,这样写也是可以的。

AC代码如下:(对于质数来说,显然直接判断要比分解来得快,所以直接可以输出答案)

#include#include#include#include#includeusing namespace std;#define N 1000010 int cnt1,cnt2,prime[N],p[100],e[100],ans[100];bool notprime[N];void init(){cnt1=0;notprime[1]=1;for(int i=2;i1){p[cnt2]=n,e[cnt2++]=1;}}bool isprime(int n){if(n==1)return false;for(int i=2;i<=sqrt(n);i++){if(n%i==0)return false;}return true;}int main(){init();int t;scanf("%d",&t);while(t--){int n;scanf("%d",&n);if(n==1){printf("1\n");continue;}bool c=isprime(n);if(n%4==1&&c){printf("12\n");}else if(c){printf("4\n");}else{fenjie(n);int s=1;memset(ans,0,sizeof(ans));for(int i=0;i

原创粉丝点击