输出[a,b]内的所有完数
方式一
#include<stdio.h>
void Judge(int a,int b){
int i,j,t;
for(i=a;i<=b;i++){//遍历[1,b]内的每个数,找因子
t = 1;
for(j=2;j<i;j++){//找因子
if(i%j == 0) t+=j;
}
if(t == i && t>a) printf("%d\n",t);
}
}
int main(void){
int a,b;
scanf("%d %d",&a, &b);
Judge(a,b);
return 0;
}
方式二
#include<stdio.h>
int function( int n );
int main(void){
int a, b, i;
scanf( "%d %d", &a, &b );
for( i = a; i <= b; i++ ){
if( function(i) == 1){
printf( "%d\n", i);
}
}
return 0;
}
int function( int n ){
int i, sum = 0;
if( n == 1) return 0;
for( i = 2; i < n; i++ ){
if( n % i == 0){
sum += i;
}
}
if ( sum + 1 == n ) return 1;
return 0;
}
前一种方式是第一次做这个题目时写的,第二种方式是复习的时候重新写的,代码风格还是变化了一丢丢hhh。
最大公约数
方式一
#include<stdio.h>
void gcd(int a, int b){
int i,j,max=1;
if(!a){//a=0
if(b == 1)
max = 1;
else//b不为1
max = b;
}
else if(!b){//b=0
if(a == 1)
max = 1;
else//a不为1
max = a;
}
else{//a,b均不为1,0
if(a<b){
for(i=2;i<=a;i++){
if(a%i == 0 && b%i == 0) max = i;
}
}
else{
for(i=2;i<=b;i++){
if(a%i == 0 && b%i == 0) max = i;
}
}
}
printf("%d\n",max);
}
int main(void){
int a,b;
scanf("%d %d", &a, &b);
gcd(a,b);
return 0;
}
方式二
#include<stdio.h>
int main( void ){
int m, n, r;
scanf( "%d %d", &m, &n );
r = m % n;
while( r ){
m = n;
n = r;
r = m % n;
}
printf( "%d\n" , n );
return 0;
}
方式二是在初步了解算法之后学到的,辗转相除法。方式一是百度的定义然后从定义出发分类讨论写的。
角谷定理验证
#include<stdio.h>
int main( void ){
int n,count = 0;
scanf( "%d\n", &n );
while( n != 1){
if( n %2 == 0){
n = n /2;
count++;
}
if( n % 2 !=0 ){
n = 3 * n + 1;
count++;
}
}
printf( "%d\n", count);
return 0;
}
代码还可以再简洁一点,把n % 2 != 0
简化为!( n % 2 )
等。
验证哥德巴赫猜想
方式一
#include<stdio.h>
int Isright(int n){
int i;
for(i=2;i<n/2;i++){
if(n%i == 0) return 0;//是
}
return 1;
}
int main(void){
int n,i,k=0,a[10],j=0;
scanf("%d\n",&n);
if(!(n%2)){
for(i=2;i<n/2;i++){
k = n - i;
if(Isright(k)&&Isright(i)) a[j++]=i;
}
}
printf("%d %d\n",a[0], n-a[0]);
return 0;
}
方式二
#include<stdio.h>
#include<math.h>
int prime( int n );
int main( void ){
int n,i;
scanf( "%d", &n);
if( n % 2 == 0 ){
for( i = 2; i < n ; i++ ){
if( prime(i) && prime(n-i)){
printf( "%d %d\n", i, n-i);
break;
}
}
}
return 0;
}
int prime( int n){
int i,sqr;
if( n < 1) return 0;
sqr = (int)sqrt( 1.0 * n );
for( i = 2; i <= sqr; i++ ){
if( n % i == 0 ) return 0;
}
return 1;
}
其实重点在于定义一个判断素数的函数,(素数判断也是C语言流程控制里一个比较经典的题目),有多种定义方式,看自己喜好。方式一是我自己根据定义写的,OJ上是过了的,但是也有可能存在一些边界或者是其他的什么问题没有考虑到,方式二应该算是一种比较经典的判断素数的函数(从算法书上看到的),比较简洁。把判断条件sqr单独拎出来在循环之前定义,减少了sqr的运算次数,在n比较大的时候优点比较明显。如果放在循环条件里,每一次循环都要计算一次sqr,就比较繁琐。
折点计数
#include<stdio.h>
int main( void ){
int n, i, count = 0;
scanf( "%d\n", &n );
int a[n];
for( i = 0; i < n; i++ ){
scanf( "%d ", &a[i]);
}
for( i = 1; i < n - 1; i++ ){
if( a[i-1] < a[i] && a[i+1] < a[i] ){
count++;
}
if( a[i-1] > a[i] && a[i+1] > a[i] ){
count++;
}
}
printf( "%d\n", count);
return 0;
}
还是要从折点的定义出发,难点应该是在边界控制上,数组下标从0开始,n-1结束,判断需要涉及三个点,那么i应该从1开始,取到n-1-1结束,即i<n-1,左右边界判断好即可。