题目链接:click here~~
最近复习数论的知识。发现这道题不错,发现既然没有记录,果断的再做了一遍。
题意:给定一个整数n,要求我们求出n的最大素因子的序数,例如:2的序数是1,3的序数是2,5的序数是3,以此类推.
思路:开一个数组, 直接记录素数的序数。
从2开始循环,当遇到为0的值时,证明它是素数,这时候把它的所有倍数(包括它本身)的值更新为这个素数的序数,也就同时标记为它们为非素数。
这样,每个数的序数可以保证是最大的。
#include<cmath> #include<queue> #include<deque> #include<stack> #include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> using namespace std; int prime[1000000+10]; int main() { int i,j,k,n,t; memset(prime,0,sizeof(prime)); prime[1]=0; t=0; for(i=2; i<=1000000; i++) if(!prime[i]) { prime[i]=++t; for(j=2; i*j<=1000000; j++) prime[i*j]=prime[i]; } while(scanf("%d",&n)!=EOF) { printf("%d\n",prime[n]); } return 0; }今天看到强哥的代码,发现自己之前写的这类分解素因子的代码有点太简单 。
数据大的情况了,可能会出错,
以后注意一点,尽量考虑其他方面。
#include <stdio.h> const int M = 1000001; int prime[78500]; int pos[M]; void ac_table() { int top=0; for(int i=2;i<M;i++) if(pos[i] == 0) { prime[++top]=i; //放入素数表 pos[i] = top; //记录此素数的序数 for(int j=2*i;j<M;j+=i) pos[j] = -1; //标记为非素数 } } int main() { int n; ac_table(); while(~scanf("%d",&n)) { int ans=0; for(int i=1;prime[i]*prime[i]<=n;i++) //循环结束条件是亮点,以前我写的是n!=1 while(n%prime[i]==0) { ans = i; //ans记录序数 n /= prime[i]; } if(n!=1) //还没分解完,说明此时n是素数 ans = pos[n]; //直接把n的序数赋给ans printf("%d\n",ans); } return 0; }