寒假训练 2笔记

1.求一个数的因数即因数之和

方法一

for(i=1;i<n;i++)//n为被分解的的数
{
 if(n%i==0)
 sum+=i;
}

emmm超时了,明天在更进。。。。

注意点

1.输入多个字符串时`

while(gets(s))//这样既可
while(gets(s)!=EOF//会报错!!!

2.回文质数(洛谷和vjudge都做过)
ps:一个数既是回文数又是素数
原先的想法

写两个函数,一个判断素数,一个判断回文,超时了。。。

看了题解之后

构造回文数
!!!偶数位的回文质数只有11
于是我们可以先判断位数
再分别构造位数为3,5,7的回文质数

#include<stdio.h>
#include<math.h>
int length(int n)
{
	int count=0;
	while(n)
	{
		count++;
		n=n/10;
	}
	return count;
}
int prime(int n)     
{
	int i ; 
    for(i=2;i<=sqrt(n);i++)
    if(n%i==0) return 0;
    return 1;
}
int main()
{
	int i=4,a,b,c[100005]={5,7,11},d[10005],count=0;
	int d1,d2,d3,d4,t;
	
    while(scanf("%d %d",&a,&b)!=EOF)
    {       count=0;
    		for(d1=1;d1<=9;d1+=2) //保证最后一位是奇数      
        for (d2 = 0; d2 <= 9; d2++)
            if(length(a)<=3&&length(b)>=3&&prime(100*d1 + 10*d2 + d1))//构造回文素数 
                c[i++]= 100*d1 + 10*d2 + d1;
    for(d1=1;d1<=9;d1+=2)     
	    for(d2=0;d2<=9;d2++)
		    for(d3=0;d3<=9;d3++)    
			   if(length(a)<=5&&length(b)>=5&&prime(10000*d1+1000*d2+100*d3+10*d2+d1))
			     c[i++]= 10000*d1+1000*d2+100*d3+10*d2+d1;
				   
	for(d1=1;d1<=9;d1+=2)
	for(d2=0;d2<=9;d2++)
	for(d3=0;d3<=9;d3++)
	for(d4=0;d4<=9;d4++)
	if(length(a)<=9&&length(b)>=7&&prime(1000000*d1+100000*d2+10000*d3+1000*d4+100*d3+10*d2+d1))
	c[i++]=1000000*d1+100000*d2+10000*d3+1000*d4+100*d3+10*d2+d1;
	for(i=0;i<10005;i++) 
	{
		if(c[i]>=a&&c[i]<=b)
		{
			d[count++]=c[i];
		}
	}
	for(i=0;i<count;i++)
	printf("%d\n",d[i]);
	printf("\n");
	}
	return 0;
}

3.坑点
1<num1,num2<10000
num1和num2没有明确大小,需要判断
4.

已经知道现有会员N人,把会员从1到N编号,其中会长的号码是N号,凡是和会长是老朋友的,那么该会员的号码肯定和N有大于1的公约数,否则都是新朋友,现在会长想知道究竟有几个新朋友

##解题思路
原先:写一个判断两个数最大公约数的函数,从1到n-1每一个数与n判断最大公约数,如果是1,则为新朋友,count++
又又又超时了。。。。
后来:
1.将n的所有因数存放进一个数组里
2.从1到n-1每个数判断过去(记为i),因数数组遍历,只要i%因数==0,就count++(代表老朋友),break,进入下一个数的判断
3.输出n-count-1

#include<stdio.h>
int main()
{
	int n,num,i,count,yin[1000],k,j,m,mm;
	scanf("%d",&n);
	for(mm=1;mm<=n;mm++)
	{   k=0;count=0;
		scanf("%d",&num);
		for(i=2;i<num;i++)
		{
			if(num%i==0)
			yin[k++]=i;
		}
		for(j=1;j<num;j++)
		{
			for(m=0;m<k;m++)
			{
				if(j%yin[m]==0){
				count++;break;}
			}
		}
		printf("%d\n",num-count-1);
	}
	return 0;
}

5.学习使用qsort函数的用法,从小到大
一个数组里两两相加的和放在应一个数组里
从大到小排序,逆序输出m个即可

#include<stdio.h>
#include<stdlib.h>
int b[5000000];
int cmp(const void *a,const void *b)
{
	return *(int *)a-*(int *)b;
}
int main()
{
    int m,n,a[3000],i,j,k,r,x,ii;
    while(scanf("%d %d",&n,&m)!=EOF)
    {   r=0;
    	for(i=0;i<n;i++)
    	scanf("%d",&a[i]);
    	qsort(a,n,sizeof(a[0]),cmp);
        for(i=n-1;i>=1;i--)
        {
        	for(k=i-1;k>=0;k--)
        	{
        		b[r++]=a[i]+a[k];
			}
		}

		qsort(b,r,sizeof(b[0]),cmp);
		for(i=r-1;i>r-m;i--)
		printf("%d ",b[i]);
		printf("%d\n",b[r-m]);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值