练习1: 判断一个数是否是质数
质数:除了1 和它本身,没有其它的数将其整除,为了提高效率我们只需要除到它的一半就可以了。
参考代码:
int i;
int j = 2;
scanf("%d",&i);
while(j <= i / 2)//除到它的一半就可以了
{
//找到能将其整除的那个数
if(i % j == 0)//说明能整除 那么这个玩意儿就不是质数
{
//你已经知道它是质数了 就没有必要往下面走了
printf("%d 不是质数\n",i);
break;
}
//没有整除的情况下你就要往下面继续尝试
j++;
}
//什么时候说明它是质数
//如果是质数 那么上面的if就永远进不去
//那么就不会被break
//说明这个j一直在递增
//它的退出为while为假了退出的
if(j > i / 2)
{
printf("%d 是质数\n",i);
}
练习2: 求1000以内所有的完数
完数:除了它本身以外的所有的因子的和如果和它相等,那么这个数就是完数
eg:
6:除了它本身以外的因子有 1 2 3
6 = 1 + 2 + 3;
所以6是一个完数
找因子实际上就是找能否被整除的事情,又是除到i / 2,发现能被整除,将这个除数加上 sum += j;
这里就不能break,最后while正常退出,判断sum和i是否相等,就是求质数的过程
参考代码:
#include <stdio.h>
int main()
{
int i = 1;
int a = 1;
int sum = 0;
while(i < 1000)
{
while(a < i)
{
if(i % a == 0)
sum += a;
a++;
}
if(sum == i)
printf("完数有%d\t",i);
sum = 0;
i++;
a = 1;
}
printf("\n");
return 0;
}
练习3: 求两个正整数的最大公约数与最小公倍数
公约数:这个数能将他们两个全部整除
最大的公约数为这些约数里面的最大值
最小公倍数:a * b / 最大公约数
我们可以采用辗转相除法:a > b,mod为余数,大数除小数得到余数,然后将小数转为大数,余数转为小数,无限的进行,直到余数为0,小数这个时候就是最大公约数。
参考代码一:也就是说从大找到小
#include <stdio.h>
int main()
{
int a,b;
int mod;//余数
scanf("%d%d",&a,&b);
int sum = a * b;
if(!a || !b)//只要有一个0就退出
return -1;
while(mod = a % b)
{
a = b;
b = mod;
}
printf("最大公约数为:%d\n最小公倍数为:%d\n",b,sum / b);
return 0;
}
参考代码二:从小找到大
#include <stdio.h>
int main()
{
int a,b;
int i = 1;
int c;
int max,min;
scanf("%d%d",&a,&b);
if (a >b)
c = a;
else
c = b;
while(i < c )
{
if (a % i == 0&&b % i == 0)
max = i; //这个过程中一直更新这个值
min = a * b / max;
i++;
}
printf("最大公约数为%d,最小公倍数为%d\n",max,min);
return 0;
}
练习4: 求s = a + aa + aaa + a...a;//最后有n个a
a:1 ~ 9也自己输入,n:自己输入 不要越界
最终输出他们的和
参考代码:
#include <stdio.h>
int main()
{
int a,n,i;
printf("输入a的值\n以及有n个连体a相加\n");
scanf("%d%d",&a,&n);
int s = 0,b =0;
for(i = 0 ; i < n ; i++)
{
b += a;
a *= 10;
s += b;
}
printf("它们的和为%d\n",s);
return 0;
}
练习5: 求10000000!末尾有多少个0
要想得到0 就只有一种情况 2 * 5, 也就是看一个数里面有多少个2与5的因子3 * 10 = 3 * 2 * 5
2的个数明显比5要多 ,因此我们只需要看这个数里面有多少个5的因子就可以了,也就是所有的数里面有多少个5的因子,那么末尾就是多少个0
参考代码:
#include <stdio.h>
int main()
{
int sum = 0;
int i = 2;
while(i <= 10000000)
{
int j = i;
while(j % 5 == 0)//能将5整除就进来
{
//将5取出
j /= 5;
sum++;
}
i++;
}
printf("10000000!末尾有 %d 个0\n",sum);
return 0;
}
练习6: 连续的正整数之和问题
输入一个正整数,这个正整数可能会写成连续的整数之和。
eg:
15 = 1 + 2 + 3 + 4 + 5
15 = 4 + 5 + 6
15 = 7 + 8
找出所有的可能
参考代码:
#include <stdio.h>
int main()
{
int left = 1,right = 2;
int sum = 3;
int n;
scanf("%d",&n);
while(left < right)
{
if(sum < n)//和还不够 增长右边
{
right++;
sum += right;
}
else if(sum > n)//和超过了 缩小左边的
{
sum -= left;
left++;
}
else//相等 找到了
{
printf("[%d,%d]\n",left,right);
right++;//继续
sum += right;
}
}
return 0;
}
练习7: 将一个正整数分解质因数
eg:
90 = 2 * 3 * 3 * 5
8 = 2 * 2 * 2
15 = 3 * 5
参考代码:
#include <stdio.h>
int main()
{
int n;
scanf("%d",&n);
int i = 2;
printf("%d = 1",n);
while(i <= n)//3
{
if(n % i == 0)//能整除就拿
{
printf(" * %d",i);
n /= i;
//i有可能有多个
continue;
}
i++;
}
printf("\n");
return 0;
}
练习8: 求15的1024次方末尾三位是多少
提示:只跟后面的三位相关
15 * 15 = 225
225 * 15 = 3375
下一次就用
375 * 15 = 5625
625 * 15......
每次都只保留个十百
参考代码:
#include<stdio.h>
int main()
{
int i = 2;
int a = 15, c = 15;
int v;
while(i <= 1024)
{
c *= a;
v = c % 1000; //用变量V保存c的后三位,通过对1000取余得到一个数后三位
c = v; //把保存下来的值给c
i++;
}
printf("15的1024次方末尾三位是%d",v);
return 0;
}
练习9: 现在有一个30个元素的数组,里面的数据未知,现在我需要知道其中的一些元素的和为一个值(值为多少自己指定),求出所有的可能:
eg:
int a[5] = {10,12,2,14,8};
//我现在需要直到有哪些元素的和为22
//根据现在的数据来说就是
a[0] + a[1]
a[3] + a[4]
a[2] + a[3] + a[4]
部分和问题,用穷举法列出所有可能,需要用到格雷码。
格雷码:不是参与运算,它只是代表了一种可能,也就是我们要利用这个码来找到可能.
#include <stdio.h>
#include <math.h>
#define N 5
int main()
{
int a[N] = {10,12,2,14,8};
int sum = 0;
int n = 22;
//需要直到和为n
for(int i = 1;i < pow(2,N);i++)
{
sum = 0;
//选中的元素实际上对应的就是i的bit为1的那些玩意儿
for(int j = 0;j < N;j++)
{
if(i & 1 << j)//判断bit是否为1
{
sum += a[j];
}
}
if(sum == n)//找到了 把i里面bit为1的位置的元素打印出来就ok
{
printf("和为 %d 的序列为:",n);
for(int j = 0;j < N;j++)
{
if(i & 1 << j)//判断bit是否为1
{
printf("%d ",a[j]);
}
}
printf("\n");
}
}
return 0;
}