做数论的时候往往题目都不算难,但是一写就超时,总是习惯性用暴力解决问题,但是事实上有很多需要不停积累的省时小技巧
Largest prime factor
Everybody knows any number can be combined by the prime number.
Now, your task is telling me what position of the largest prime factor.
The position of prime 2 is 1, prime 3 is 2, and prime 5 is 3, etc.
Specially, LPF(1) = 0.
InputEach line will contain one integer n(0 < n < 1000000).
OutputOutput the LPF(n).
Sample Input
1
2
3
4
5
Sample Output
0
1
2
1
3
我刚开始的方法是在题目范围内暴力算出所有素数,然后把所有素数存储在数组里,毫无疑问,这个方法超时,用素数打表法,将素数存储在数组中,可以大大减少时间复杂度
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define N 1000000
using namespace std;
int pos[N+5];
int ans=1;
int main()
{
for(int i=2;i<=N;i++)
{
if(!pos[i])
{
pos[i]=ans;
for(int j=i+i;j<=N;j+= i)
pos[j]=ans;
ans++;
}
}
int n;
while(~scanf("%d",&n))
printf("%d\n",pos[n]);
return 0;
}
HDU – 2854 Central Meridian Number
A Central Meridian (ACM) Number N is a positive integer satisfies that given two positive integers A and B, and among A, B and N, we have
N | ((A^2)*B+1) Then N | (A^2+B)
Now, here is a number x, you need to tell me if it is ACM number or not.
InputThe first line there is a number T (0<T<5000), denoting the test case number.
The following T lines for each line there is a positive number N (0<N<5000) you need to judge.OutputFor each case, output “YES” if the given number is Kitty Number, “NO” if it is not.Sample Input
2
3
7
Sample Output
YES
NO
这个题我刚开始毫无头绪,用笔在纸上划拉划拉也没找到什么规律,想着直接用代码输出可行数试试,然后意外学会了打表法
#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <functional>
using namespace std;
bool vis[10000005];
void calculate()
{
for(int i=1; i<=5000; i++)
{
for(int j=1; j<=1000; j++)
{
for(int k=1; k<=1000; k++)
{
if((j*j*k+1)%i==0&&(j*j+k)%i!=0)
{
vis[i]=true;
break;
}
}
if(vis[i])
break;
}
}
for(int i=1; i<=5000; i++)
if(!vis[i])
cout<<i<<endl;
}
void solve()
{
vis[1] = true;
vis[2] = true;
vis[3] = true;
vis[4] = true;
vis[5] = true;
vis[6] = true;
vis[8] = true;
vis[10] = true;
vis[12] = true;
vis[15] = true;
vis[16] = true;
vis[20] = true;
vis[24] = true;
vis[30] = true;
vis[40] = true;
vis[48] = true;
vis[60] = true;
vis[80] = true;
vis[120] = true;
vis[240] = true;
}
int main()
{
int t, a;
cin >> t;
///calculate();
solve();
while (t--)
{
scanf("%d", &a);
if (vis[a])
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
七夕节
七夕节那天,月老来到数字王国,他在城门上贴了一张告示,并且和数字王国的人们说:“你们想知道你们的另一半是谁吗?那就按照告示上的方法去找吧!”
人们纷纷来到告示前,都想知道谁才是自己的另一半.告示如下:
数字N的因子就是所有比N小又能被N整除的所有正整数,如12的因子有1,2,3,4,6.
你想知道你的另一半吗?
Input输入数据的第一行是一个数字T(1<=T<=500000),它表明测试数据的组数.然后是T组测试数据,每组测试数据只有一个数字N(1<=N<=500000).
Output对于每组测试数据,请输出一个代表输入数据N的另一半的编号.
Sample Input
3
2
10
20
Sample Output
1
8
22
本题需要注意的是因子是成对出现的,求出其中一个另外一个自然就出来,而且数据较多,开根号处理即可
#include<iostream>
#include<cmath>
using namespace std;
const int N=500002;
int a[N],n,t;
void solve()
{
for(int i=1; i<=N/2; i++)
for(int j=2*i; j<=N; j+=i)
a[j]+=i;
}
int main()
{
cin>>t;
solve();
while(t--)
{
cin>>n;
cout<<a[n]<<endl;
}
return 0;
}
数论的知识比较多也比较杂,需要做大量的题去积累经验,积累做题技巧,现在的我还是经常偷懒,经常想着用暴力解决问题,即使知道暴力有可能超时还是想偷懒试一下,以后还是得多动脑,多总结,争取能早日学会用巧妙的办法解决问题。