http://codeforces.com/problemset/problem/1076/B
You are given an integer number nn. The following algorithm is applied to it:
- if n=0, then end algorithm;
- find the smallest prime divisor dd of n;
- subtract dd from nn and go to step 1.
Determine the number of subtrations the algorithm will make.
Input
The only line contains a single integer nn (2≤n≤10^10).
Output
Print a single integer — the number of subtractions the algorithm will make.
Examples
Input
5
Output
1
Input
4
Output
2
Note
In the first example 5 is the smallest prime divisor, thus it gets subtracted right away to make a 0.
In the second example 2 is the smallest prime divisor at both steps.
题目大意:给你一个大于n的数,进行三步操作:(1)找到这个数的最小的质因子。(只有一个质因子的数就是素数 1没有质因子)(2)令n减去这个质因子。(3)若n=0,退出,否则进行步骤(1)。最后让你输出操作的次数。
思路:每个正整数都能够以唯一的方式表示成它的质因数的乘积。所有的质数都是奇数除了2,那我们先考虑n是偶数的情况:(1)偶数的最小质因子一定是2,偶数减去2仍然是2,因此偶数的操作次数就是n/2。(2)如果n不是偶数,n又能表示成质因数乘积的形式,因此我们可以认为n能表示成奇数乘积的形式,我们可以假设n=a*b,a是n的最小质因子,那么n-a=a*(b-1),因为b是一个奇数,所以b-1就是偶数,即n-a是偶数,那么由(1)知,操作次数为1+(n-a)/2。所以我们把平时写的判断素数的函数改一下:若n是素数,则返回n;若n不是素数,则返回n的最小质因子。这样这道题就很容易了。(其实这样写的话,所有的数都可以统一起来,不必分奇偶)
#include<iostream>
#include<cstdio>
#include<stack>
#include<cmath>
#include<cstring>
#include<queue>
#include<map>
#include<set>
#include<algorithm>
#include<iterator>
#define INF 0x3f3f3f3f
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
ll prime(ll n)
{
if(n==2||n==3)
return n;
for(ll i=2;i*i<=n;i++)
{
if(n%i==0)
return i;
}
return n;
}
int main()
{
ll n;
scanf("%lld",&n);
if(n%2==0) //偶数必定一直减2
printf("%lld\n",n/2);
else
{
n-=prime(n);
printf("%lld\n",1+n/2);
}
return 0;
}