目录
1.求区间内素数个数问题
法1:
#include <stdio.h>
#include <stdlib.h>
#define p 1000005
#include <stdio.h>
int num[p];
int main()
{
int i,j;
for(i=2;i<p;i++)
num[i]=1;
for(i=2;i<p;i++)
{
if(num[i]){
for(j=2;i*j<p;j++){
num[i*j]=0;
}
}
}//此时,所有值为1的num[i]中的i为素数
for(i=1;i<p;i++){
num[i]=num[i]+num[i-1];
}//num[i]为从1到i的素数个数
int a,b,n,temp;
scanf("%d",&n);
while(n--){
scanf("%d%d",&a,&b);
if(a>b){
temp=a;
a=b;
b=temp;
}
printf("%d\n",num[b]-num[a-1]);
}
return 0;
}
法2:
#include <stdio.h>
#include <stdlib.h>
#define p 1000005
#include <stdio.h>
int num[p];
int main()
{
num[0]=1;
num[1]=1;//1代表非素数,0代表素数
int i,j;
for(i=2;i<p;i++){
if(!num[i]){
for(j=2*i;j<p;j=j+i){
num[j]=1;
}
}
}
int a,b,n,temp;
scanf("%d",&n);
while(n--){
scanf("%d%d",&a,&b);
if(a>b){
temp=a;
a=b;
b=temp;
}
int count=0;
for(int i=a;i<=b;i++){//直接在a和b范围内数素数的个数
if(!num[i])
count++;
}
printf("%d\n",count);
}
return 0;
}
法3:
#include<cstdio>
#include<algorithm>
using namespace std;
int s[1000050];
int noprime[1000050];
int main() {
noprime[0] = 1;
noprime[1] = 1;
for(int i = 2; i<= 1000000; i++) {
if(!noprime[i]) {
for(int j = 2*i; j<= 1000000; j+=i) {
noprime[j] = 1;
}
}
}
s[0] = 0;
for(int i = 1; i<= 1000000; i++) {
if(noprime[i]==1) s[i] = s[i-1];
else if(noprime[i]==0) s[i]=s[i-1]+1;
}
int k;
scanf("%d",&k);
while(k--) {
int a,b;
scanf("%d%d",&a,&b);
if(a>b) swap(a,b);
if(a==0) printf("%d\n",s[b]);
else printf("%d\n",s[b]-s[a-1]);
}
}
参考:湘潭大学OJ-1098求区间内素数个数问题_xtuzxj的博客-CSDN博客
2.欧拉函数
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int main()
{
int n;
while(scanf("%d",&n)!=EOF){
if(n==0) break;
if(n==1)
{printf("0");
continue;
}
int ans=n;
for(int i=2;i<=sqrt(n);i++){
if(n%i==0){
while(n%i==0){
n=n/i;
}
ans/=i;
ans*=(i-1);
}
}
if(n!=1){
ans/=n;
ans*=(n-1);
}
printf("%d\n",ans);
}
}
3.GCD
解法
与六互素就是不能是二的倍数也不能是三的倍数,所以这道题就是求一个范围内不是二和三的倍数的数字的个数。一个数(假设这个数是b)除以三(取整)就是[1, b]内的三的倍数的个数,同理,一个数除以二(取整)就是[1, b]二的倍数的个数。但是,有些数字即是二的倍数,又是三的倍数,这时候要把这些数字减去。求[a, b]区间内的这样的数的个数可以这样做,先求[1, b]内这样的数字的个数。再求[1, a-1]区间内这样数字的个数
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int fun(int a, int b) {
int a3 = b / 3;
int a2 = b / 2;
int a6 = b / 6;
return b - (a3 + a2 - a6);
}
int main(int argc, char const **argv) {
int K;
scanf("%d",&K);
while(K--) {
int a,b;
scanf("%d%d",&a,&b);
int s = fun(1, b);
int m = fun(1, a - 1);
printf("%d\n", s-m);
}
return 0;
}
参考:XTUOJ-1296-GCD_轨迹 的博客-CSDN博客
4.无暇素数
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int judge(int x) {
if(x==1) return 0;//不是素数
for(int i=2;i<=sqrt(x);i++){
if(x%i==0)
return 0;
}
return 1;
}
int main() {
int K;
scanf("%d",&K);
while(K--) {
int n;
scanf("%d",&n);
int m=n;
int flag=1;
int an=1;
while(m>0){//计算该数有多少位,并判断是否有前导0(包括最后一位是不是0)
if(m%10==0){
flag=0;//有0
}
an*=10;
m/=10;
}
if(flag==1){
for(int i=an;i>=10;i/=10){//从该数本身,到依次去除最高位得到的数
if(judge(n%i)==0){
flag=0;
break;
}
}
}
if(flag) printf("Yes\n");
else printf("No\n");
}
return 0;
}
参考:湘大OJ1295Flawless Prime_xtuzxj的博客-CSDN博客
5.质因数分解
从i=2到 i*i<=n循环,当遇到一个n%i=0的情况,就算是找到了一个质因数。注意最后n不是0的情况。比如说 求6得质因子个数,当i*i<=6时结束循环,此时i一定是小于3的,按照我们的分析 6应该包含2个质因子(2和3),所以当循环完毕时,要判断一下 n此时的值,若为1 说明已经把质因数找完,若不为1,那么剩下的一定是个质数。
这个题还要注意输出的问题,使用”^”表示幂,”*”表示乘。
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int main() {
int n;
while(scanf("%d",&n)!=EOF) {
int an = 0;//an这个变量在存储找到的不同质因数的个数
for(int i = 2; i*i<= n; i++) {
if(n%i==0) {
int count = 0;//count这个变量储存每个质因数的个数
while(n%i==0) {
count++;
n /= i;
}
if(an!=0) printf("*");
if(count!=1) printf("%d^%d",i,count);
else if(count==1) printf("%d",i);
an++;
}
}
if(an==0) printf("%d\n",n);
else {
if(n!=1) printf("*%d\n",n);
else if(n==1) printf("\n");
}
}
return 0;
}
6.A+BVIII
求能被整除的数其实就是求因子,比如说 一个数中质因数分解后有3个2,也就是 2^3 × \times ×(此处省略一堆质因数分解),那么1(2的0次方),2(2的1次方),4(2的2次方),8(2的3次方)都是这个数的因数,也就是都可以被这个数整除,那么假如说 一个数被分解成了 2∧3 × \times × 3∧2,那么其实他就有(3+1) × \times ×(2+1)个因子,因为由2构成的因子有4个(1,2,4,8) ,由3构成的因子就有3个(1,3,9)所以这些个数乘起来也是那个数的因子。
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int main() {
int k;
scanf("%d",&k);
while(k--) {
int a,b;
scanf("%d %d",&a,&b);
int x = a+b;
int ans = 1;//因为要进行×的运算,所以要初始化为1
for(int i = 2; i*i <= x; i++) {
if(x%i==0) {
int count = 0;
while(x%i==0) {
count++;
x /= i;
}
ans *= (count+1);
}
}
if(x!=1) printf("%d\n",ans*2); //如果最后剩下的数不是1 那么一定还有一个质因子
else printf("%d\n",ans);
}
}
参考:湘大1218 A+BVIII_xtuzxj的博客-CSDN博客
7.Alice and Bob
n位数最大数是10^n-1,这个数除m向下取整得到的商再减去n-1位数最大的数除以m得到的商就是他们都喜欢的数。注意数的范围别溢出就好
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int main() {
int k;
scanf("%d",&k);
unsigned long long temp;
while(k--)
{
int n,m;
scanf("%d%d",&n,&m);
temp=(unsigned long long)pow(10,n)-1;
unsigned long long cnt=temp/m-temp/10/m;
if(n==1){
cnt++;
}
printf("%ld\n",cnt);
}
return 0;
}