Jack's Blog

流淌的心,怎能阻拦,吹来的风,又怎能阻挡。

C language programming learning 7

1.

//编程实现找出字符串中最大字符元素并输出该元素及其对应的ASCII值.
//****要求输入提示信息为:
//"Input a string:\n"
//****输出格式要求为:
//"The largest character of \"%s\" is \'%c\' ,The ASCII is %d."
#define N 100
#include<stdio.h>
#include<string.h>
main()
{

    printf("Input a string:\n");
    char c[N];
    gets(c);
    char d=c[0];
    int i;
    for(i=1;i<=strlen(c);i++)
    {
        if(d<c[i])
            d=c[i];
    }
    printf("The largest character of \"%s\" is \'%c\' ,The ASCII is %d.",c,d,d);
}

2.

按如下函数原型编程计算并输出n×n阶矩阵的转置矩阵。其中,n由用户从键盘输入。已知n值不超过10。
void Transpose(int (*a)[N], int n);
void  Swap(int *x, int *y);
void InputMatrix(int (*a)[N], int n);
void PrintMatrix(int (*a)[N], int n);
输入提示信息:"Input n:"
输入格式:"%d"
输入提示信息:"Input %d*%d matrix:\n"
输出提示信息:"The transposed matrix is:\n"
输出格式:"%d\t"

#include <stdio.h>
#define N 10
void  Swap(int *x, int *y);
void Transpose(int (*a)[N], int n);
void InputMatrix(int (*a)[N], int n);
void PrintMatrix(int (*a)[N], int n);
int main()
{                
    int s[N][N], n;
    printf("Input n:");
    scanf("%d", &n);
    InputMatrix(s, n);
    Transpose(s, n);
    printf("The transposed matrix is:\n");
    PrintMatrix(s, n);
    return 0;
}                
/* 函数功能:交换两个整型数的值 */
void  Swap(int *x, int *y)
{                
    int  temp;
    temp = *x;
    *x = *y;
    *y = temp;
}                
/* 函数功能:计算n*n矩阵的转置矩阵 */
void Transpose(int (*a)[N], int n)
{                
    int i, j;
    for (i = 0; i < n; i++)
    {                
        for (j = i; j < n; j++)
        {                
            Swap(*(a + i) + j, *(a + j) + i);
        }
    }
}                
/* 函数功能:输入n*n矩阵的值 */
void InputMatrix(int (*a)[N], int n)
{                
    int i, j;
    printf("Input %d*%d matrix:\n", n, n);
    for (i = 0; i < n; i++)
    {                
        for (j = 0; j < n; j++)
        {                
            scanf("%d", *(a + i) + j);
        }
    }
}                
/* 函数功能:输出n*n矩阵的值 */
void PrintMatrix(int (*a)[N], int n)
{                
    int i, j;
    for (i = 0; i < n; i++)
    {                
        for (j = 0; j < n; j++)
        {                
            printf("%d\t", *(*(a + i) + j));
        }
        printf("\n");
    }
}           

 

我的代码

#include<stdio.h>
#define N 10
void Transpose(int (*a)[N], int n)
{

    int i,j;
    for(i=0; i<n; i++)
    {
        for(j=i+1; j<n; j++)
        {
            Swap(*(a+i)+j,*(a+j)+i);
        }
    }

}

void  Swap(int *x, int *y)
{
    int temp;
    temp=*x;
    *x=*y;
    *y=temp;

}
void InputMatrix(int (*a)[N], int n)
{
    printf("Input %d*%d matrix:\n",n,n);
    int i,j;
    for(i=0; i<n; i++)
    {
        for(j=0; j<n; j++)
        {

            scanf("%d",*(a+i)+j);
        }
    }

}
void PrintMatrix(int (*a)[N], int n)
{
    int i,j;

    for(i=0; i<n; i++)
    {

        for(j=0; j<n; j++)
        {
            printf("%d\t",*(*(a+i)+j));
        }
        printf("\n");
    }
}
main()
{
    int n=100,s[N][N]= {0};

    printf("Input n:");
    do
    {

        scanf("%d",&n);

    }
    while(n>10);

    InputMatrix(s,n);
    Transpose(s,n);

    printf("The transposed matrix is:\n");

    PrintMatrix(s,n);
    return 0;
}

我个人认为,我的代码比答案还要简单,因为减少了一步不必要的计算,因此,运算时间会短一些。效率会高些!

注意:在Transpose的过程中,一定要注意一个关键性的问题

for(j=i; j<n; j++)

或者从i+1开始(i+1)效率更高,减少不必要的运算

mmp,我就是让j从0开始结果找这个错误找了一个小时,好奇啊。如果j从0开始的话,那么就相当于先把i,j互换,然后再换回来,等于说换了两次,相当于没换。

其实如果要直接输出转置矩阵,还有更简便的做法:

即:输出先j后i!无论是代码量还是计算量,都少了一大截!!!

 

#include<stdio.h>
#define N 10

void InputMatrix(int (*a)[N], int n)
{
    printf("Input %d*%d matrix:\n",n,n);
    int i,j;
    for(i=0; i<n; i++)
    {
        for(j=0; j<n; j++)
        {

            scanf("%d",*(a+i)+j);
        }
    }

}
void PrintMatrix(int (*a)[N], int n)
{
    int i,j;

    for(i=0; i<n; i++)
    {

        for(j=0; j<n; j++)
        {
            printf("%d\t",*(*(a+j)+i));
        }
        printf("\n");
    }
}
main()
{
    int n=100,s[N][N]= {0};

    printf("Input n:");
    do
    {

        scanf("%d",&n);

    }
    while(n>10);
    InputMatrix(s,n);
    printf("The transposed matrix is:\n");
    PrintMatrix(s,n);
    return 0;
}

 


题外话:

       有句mmp今天一定要讲。这种题出的简直就是多此一举

因为

我们可以认为:
int (*a)[]=int a [][]
他直接说定义一个二维数组多好

非得写这么恶心的东西的干嘛

可能他有点蛋疼
.....
因为数组作为参数类型退化成指针
int a[]写成int *a是一个意思
这跟C语言对数组的实现有关
二维数组要求第二个维度给出长度,这是因为编译器算偏移要用这个
因为你取数组里面一个元素实际上是解引用一个指针
这个指针是base+offset算出来的
 
int a[100]
a[4]等价于 *(a+4)
由加法交换性,4[a]等价于a[4],就是你可以把a[4]写成4[a]
------------------------------------------------------------------
大佬告诉我
毕竟C是一种比较低级的语言
像函数式语言是没指针的
甚至没有变量
感兴趣的话可以去玩玩haskell,这个比较典型
------------------------------------------------------------------
[]优先级比*高
int b[4][4]={0};
int (*a)[4]=b;

int b[4][4]={0};
int *a[4];
a[0]=b[0];
就是说
int *a[n]是指针数组(也就是说其本质上是数组,但里面存放的都是指针)
int (*a)[n]是数组指针(本质上是一个指针,而且是一个指向数组的指针)

第一部分:

int a[4]

a的类型是int[4],a[0]的类型是int;a是指向int[4]的指针

int (*a)[4]=b;指的是a指向的是int [4],然后把b的第一行地址赋给他

就是直接拷贝了首元素地址

第二部分很好理解

就是把b[0]的首行地址给a[4];

其实这种题完全可以用数组的方法做,看起来更加简洁,效率也几乎一样

#include<stdio.h>
#include<string.h>
#define N 4
int convertmatrix(int m[N][N])
{
    int i,j,temp;
    for(i=0;i<N;i++)
    {
        for(j=i+1;j<N;j++)
        {
            temp=m[i][j];
            m[i][j]=m[j][i];
            m[j][i]=temp;
        }
    }
    return 0;
}
int main()
{
    int matrix[N][N];
    int i,j;
    printf("请输入一个%d*%d的矩阵:\n",N,N);
    for(i=0;i<N;i++)
    {
        for(j=0;j<N;j++)
        {
            scanf("%d",&matrix[i][j]);
        }
    }
    convertmatrix(matrix);
    for(i=0;i<N;i++)
    {
        for(j=0;j<N;j++)
        {
            printf("%-3d",matrix[i][j]);
        }
        printf("\n");
    }
    return 0;
}

用指针编简直就是在浪费时间

所以。。。。

还有一种做法:

#include<stdio.h>
#include<string.h>
#define N 4
int convertmatrix(int m[N][N])
{
    int i,j,temp;
    for(i=0;i<N;i++)
    {
        for(j=i+1;j<N;j++)
        {
            temp=m[i][j];
            m[i][j]=m[j][i];
            m[j][i]=temp;
        }
    }
    return 0;
}
int main()
{
    int matrix[N][N];
    int i,j;
    printf("请输入一个%d*%d的矩阵:\n",N,N);
    for(i=0;i<N;i++)
    {
        for(j=0;j<N;j++)
        {
            scanf("%d",&matrix[i][j]);
        }
    }
    convertmatrix(matrix);
    for(i=0;i<N;i++)
    {
        for(j=0;j<N;j++)
        {
            printf("%-3d",matrix[i][j]);
        }
        printf("\n");
    }
    return 0;
}

另外一个比较类似的问题:

用指向一维数组的指针变量即二维数组的行指针作为函数参数,实现矩阵转置。按如下函数原型编程计算并输出m×n阶矩阵的转置矩阵。其中,m和n的值由用户从键盘输入。已知m和n的值都不超过10。

void Transpose(int (*a)[N], int (*at)[M], int m, int n);

void InputMatrix(int (*a)[N], int m, int n);

void PrintMatrix(int (*at)[M], int n, int m);

输入提示信息:"Input m, n:"

输入格式:"%d,%d"

输入提示信息:"Input %d*%d matrix:\n"

输出提示信息和格式:"The transposed matrix is:\n"

输出格式:"%d\t"

#include<stdio.h>

#define M 10

#define N 10

void Transpose(int (*a)[N], int (*at)[M], int m, int n);

void InputMatrix(int (*a)[N], int m, int n);

void PrintMatrix(int (*at)[M], int n, int m);

int main()

{

    int s[M][N],st[N][M],m,n;

    printf("Input m, n:");

    scanf("%d,%d",&m,&n);

    InputMatrix(s,m,n);

    Transpose(s,st,m,n);

    printf("The transposed matrix is:\n");

    PrintMatrix(st,n,m);

    return 0;

}

void Transpose(int (*a)[N], int (*at)[M], int m, int n)

{

    int i,j;

    for(i=0;i<m;i++)

    {

        for(j=0;j<n;j++)

        {

            *(*(at+j)+i)=*(*(a+i)+j);

        }

    }

}

void InputMatrix(int (*a)[N], int m, int n)

{

    int i,j;

    printf("Input %d*%d matrix:\n",m,n);

    for(i=0;i<m;i++)

    {

        for(j=0;j<n;j++)

        {

            scanf("%d",*(a+i)+j);

        }

    }

}

void PrintMatrix(int (*at)[M], int n, int m)

{

    int i,j;

    for(i=0;i<n;i++)

    {

        for(j=0;j<m;j++)

        {

            printf("%d\t",*(*(at+i)+j));

        }

        printf("\n");

    }

}

3.

从键盘任意输入一个整型表示的月份值,用指针数组编程输出该月份的英文表示,若输入的月份值不在1~12之间,则输出“Illegal month”。

**输入格式要求:"%d"  提示信息:"Input month number:"

**输出格式要求:"month %d is %s\n"

"Illegal month", "January", "February", "March", "April", "May", "June", "July", August", "September", "October", "November", "December"

程序运行示例1如下:

Input month number:5

month 5 is May

程序运行示例2如下:

Input month number:13

Illegal month

#include<stdio.h>

int main()

{

    int n;

    static char*monthName[]={"Illegal month", "January", "February", "March", "April", "May", "June", "July", “August", "September", "October", "November", "December"};

    printf("Input month number:");

    scanf("%d",&n);

    if((n<=12)&&(n>=1))

    printf("month %d is %s\n",n,monthName[n]);

    else

    printf("%s\n",monthName[0]);

    return 0;

}

4.

•编程计算2×3阶矩阵A和3×2阶矩阵B之积C。
•矩阵相乘的基本方法是:
•矩阵A的第i行的所有元素同矩阵B第j列的元素对应相乘,
•并把相乘的结果相加,最终得到的值就是矩阵C的第i行第j列的值。
•要求:
•(1)从键盘分别输入矩阵A和B,
•  输出乘积矩阵C
•(2)
•**输入提示信息为:
•输入矩阵A之前提示:"Input 2*3 matrix a:\n"
•输入矩阵B之前提示:"Input 3*2 matrix b:\n"
•**输入矩阵中每个值的格式为:"%d"
•**输出格式为:
•输出矩阵C之前提示:"Results:\n"
•输出矩阵C中每个值的格式:"%6d"
•输出矩阵C各行结束时换行
#include <stdio.h>
#define  ROW 2
#define  COL 3
void main()
{
	int a[ROW][COL], b[COL][ROW], c[ROW][ROW], i, j,k;

	printf("Input 2*3 matrix a:\n");
	for (i=0; i<ROW ;i++)
	{
		for (j=0; j<COL; j++)
		{
			scanf("%d", &a[i][j]);
		}
	}
	printf("Input 3*2 matrix b:\n");
	for (i=0; i<COL; i++)
	{
		for (j=0; j<ROW; j++) 
		{
			scanf("%d",  &b[i][j]);
		}
	}
	for (i=0; i<ROW; i++)
	{
		for (j=0; j<ROW; j++)
		{ 
			c[i][j] =   0 ;
			for (k=0; k<COL; k++)
			{
				c[i][j] = c[i][j]+a[i][k]*b[k][j] ;
			}
		}
	}
	printf("Results:\n");
	for (i=0; i<ROW; i++)
	{
		for (j=0; j<ROW; j++) 
		{
			printf("%6d", c[i][j]);
		}
		printf("\n") ;
	}
}

本次内容到此全部结束

C语言学习六

Before we go:

Hello大家好,好长时间没写程序了,不知道是不是手生了还是题目越来越难了,零分我真是越来越多了。

所以我将这些程序分享给大家

希望大家少走点弯路,也避免我以后忘记这些东西。


1.假设有40个学生被邀请来给餐厅的饮食和服务质量打分,分数划分为1~10这10个等级(1表示最低分,10表示最高分),编程统计并按如下格式输出餐饮服务质量调查结果。
Grade       Count  Histogram
1      5  *****
2     10  **********
3      7  *******
...
**输入格式要求:"%d"  提示信息:"Input the feedbacks of 40 students:\n"  "input error!\n"
**输出格式要求:"Feedback\tCount\tHistogram\n"  "%8d\t%5d\t"
程序运行示例如下:
Input the feedbacks of 40 students:
10 9 10 8 7 6 5 10 9 8
8 9 7 6 10 9 8 8 7 7
6 6 8 8 9 9 10 8 7 7
9 8 7 9 7 6 5 9 8 7
Feedback Count Histogram
       1     0
       2     0
       3     0
       4     0
       5     2 **
       6     5 *****
       7     9 *********
       8    10 **********
       9     9 *********
      10     5 *****


#include<stdio.h>
main(){
    printf("Input the feedbacks of 40 students:\n");
    int i,s[40]={0};
    int ret;
    for(i=0;i<40;i++){
            ret =scanf("%d",&s[i]);
            if(ret!=1||s[i]<1||s[i]>10)
            {
                i--;
                printf("input error!\n");
            }
    }
    printf("Feedback\tCount\tHistogram\n");
    int a[10]={0},j;
    for(i=0;i<40;i++){
        for(j=0;j<10;j++)
        {
                if(s[i]==j+1)
                a[j]++;
        }
    }
    for(i=0;i<10;i++)
 {
    printf("%8d\t%5d\t",i+1,a[i]);
    for(j=0;j<a[i];j++)
    {
        printf("*");
    }
    printf("\n");
}
}

2.如果一个正整数等于其各个数字的立方和,则该数称为阿姆斯特朗数(亦称为自恋性数)。如407=4^3+0^3+7^3就是一个阿姆斯特朗数。试编程求1000内的所有3位数的阿姆斯特朗数。
**输出格式要求:"There are following Armstrong number smaller than 1000:\n" " %d "
程序运行示例如下:
There are following Armstrong number smaller than 1000:
153  370  371  407

\\这道题比较简单,但是要注意不要使用pow函数,否则会有精度误差!
#include<stdio.h>
#include<stdio.h>
main()
{
    printf("There are following Armstrong number smaller than 1000:\n");
    int i,j,k,f;
    int a[10]={0,1,2,3,4,5,6,7,8,9},b[10]={0,1,2,3,4,5,6,7,8,9},c[10]={0,1,2,3,4,5,6,7,8,9};
    for(i=0;i<10;i++)
    {
        for(j=0;j<10;j++)
        {
            for(k=0;k<10;k++)
            {
                if(a[i]*100+b[j]*10+c[k]==powl(i,3)+powl(j,3)+powl(k,3)&&a[i]*100+b[j]*10+c[k]>1)
                printf(" %d ",a[i]*100+b[j]*10+c[k]);
            }
        }
    }
}

3.输入一个以回车结束的字符串(少于10个字符),它由数字字符组成,将该字符串转换成整数后输出。
**输入提示信息:"Enter a string: "
**输出格式要求:"digit = %d\n"
程序运行示例如下:
Enter a string: 123
digit = 123

#include <stdio.h>

int main(void)
{
    int i, n;
    char s[10];

    /* 输入字符串 */
    printf("Enter a string: ");  /* 输入提示 */
    i = 0;
    while ((s[i] = getchar( )) != '\n')
        i++;
    s[i] = '\0';

    /* 将字符串转换为整数 */
    n = 0;
    for (i = 0; s[i] != '\0'; i++)
        if (s[i] <= '9' && s[i] >= '0')
            n = n * 10 + (s[i] - '0');
        else                /* 遇非数字字符结束转换 */
            break;
    printf("digit = %d\n", n);

    return 0;
}

4.走台阶

楼梯有10阶台阶,上楼可以一步上1阶,也可以1步上2阶,编程计算10阶台阶总共有多少走法.
提示:可以递推计算,如1阶台阶总共一种走法,2阶台阶总共2走法,3阶台阶总共3种走法,直到计算出10阶台阶走法.

输入格式:无
输出格式:"Result=%d"

这类题一看就知道是与递归有关的问题,因此我们很容易用递归解决这道题

#include<stdio.h>
int f( int n )
{
  if ( n == 1 )
  {
    return 1;
  }
  else if ( n == 2 )
  {
    return 2;
  }
  else
  {
    return f(n-1) + f(n-2);
  }
}
int main()
{
  int num = f( 10 );
    printf("Result=%d",num);
  return 0;
}

5.选择排序法。
用选择排序法将N(N为5)个数从小到大排序后输出。
**输入格式要求:"%d" 提示信息:"Enter No.%2d:"
**输出格式要求:"%d"
程序运行示例如下:
Enter No. 1:5
Enter No. 2:7
Enter No. 3:3
Enter No. 4:9
Enter No. 5:8
35789


解法1:冒泡排序法

main()
{
    int s[N]={0},i,j,a;
    for(i=0;i<N;i++)
    {
        printf("Enter No.%2d:",i+1);
        scanf("%d",&s[i]);
 
    }
    for(j=0;j<N;j++)
    {
        for(i=0;i<N;i++)
        {
            if(s[i]>s[i+1])
            {
                a=s[i];
                s[i]=s[i+1];
                s[i+1]=a;
            }
        }
 
    }
 
    for(i=0;i<N;i++)
    {
        printf("%d",s[i]);
    }
}

几何表示:

解法2:选择排序法

#include<stdio.h>
#define N 5
main()
{
    int a[N]= {0},i,j,min,k;
    for(i=0; i<N; i++)
    {
        printf("Enter No.%2d:",i+1);
        scanf("%d",&a[i]);

    }
    for ( i = 0; i <N; i ++ )
    {
        k = i;
        for ( j = i + 1; j < N; j ++)
        {
            if ( a[ k ] > a[ j ] )
            k = j;

        }
        if(k!=i)
        {
            min = a[ i ];
            a[ i ] = a[ k ];
            a[ k ] = min;
        }
    }
    for(i=0; i<N; i++)
    {
        printf("%d\n",a[i]);
    }
}

几何表示:

 

 

C语言数据结构

1.前言

       这是属于计算机组成原理的东西,越感觉需要把C语言和数据结构学好,所以今天在次与大家分享有关C语言中的按位与(&)按位或(|)按位异或(^)取反(~)。


      由于这些运算符号都是基于二进制来说的,所以十进制的计算都需要转换成二进制。下面我们就来介绍一下二进制和十进制之间的转换:

     

2.1 二进制转十进制

1101(2)=1*2^0+0*2^1+1*2^2+1*2^3=1+0+4+8=13转化成十进制要从右到左用二进制的每个数去乘以2的相应次方
不过次方要从0开始

2.2 十进制转换二进制

十进制整数转二进制
如:255=(11111111)B
255/2=127=====余1
127/2=63======余1
63/2=31=======余1
31/2=15=======余1
15/2=7========余1
7/2=3=========余1
3/2=1=========余1
1/2=0=========余1

2.3运算操作

=== 1. and(&)运算 ===
and运算通常用于二进制取位操作,例如一个数 and 1的结果就是取二进制的最末位。这可以用来判断一个整数的奇偶,二进制的最末位为0表示该数为偶数,最末位为1表示该数为奇数.
相同位的两个数字都为1,则为1;若有一个不为1,则为0。

00111
11100
(&或者and)
----------------
00100


=== 2. or(|)运算 ===
or运算通常用于二进制特定位上的无条件赋值,例如一个数or 1的结果就是把二进制最末位强行变成1。如果需要把二进制最末位变成0,对这个数or 1之后再减一就可以了,其实际意义就是把这个数强行变成最接近的偶数。
相同位只要一个为1即为1。

00111
11100
(|或者or)
----------------
11111


=== 3. xor(^)运算 ===
异或的符号是⊕。
xor运算通常用于对二进制的特定一位进行取反操作,因为异或可以这样定义:0和1异或0都不变,异或1则取反。
xor运算的逆运算是它本身,也就是说两次异或同一个数最后结果不变,即(a xor b) xor b = a。xor运算可以用于简单的加密,比如我想对我MM说1314520,但怕别人知道,于是双方约定拿我的生日19880516作为密钥。1314520 xor 19880516 = 20665500,我就把20665500告诉MM。MM再次计算20665500 xor 19880516的值,得到1314520,于是她就明白了我的企图。
相同位不同则为1,相同则为0。


=== 4.~取反===
就是如果是00111,则变为11000

*****左移位运算符*****

 将一个数左移1位,相当于将该数乘以2;

左移2位相当于将该数乘以4,即左边数乘以2的右边数幂的积

 eg. 9<<3 的结果是:72 相当于9*2*2*2

 

*****右移位运算符*****(两边都是正数)

将一个数带符号右移1位,相当于将该数除以2(忽略余数);

带符号右移2位,相当于将该数除以4,即左边数除以2的右边数幂的商

 eg. 9>>1 的结果是:4 相当于9/2(忽略余数)

 

当左边的数字小于右边的数时,结果为0(两边都是正数)

 当左边的数小于0时,结果为:左边数的绝对值除以2的右边数幂的商的相反数-1

eg. -9>>2的结果是:-3 相当 于-(9/(2*2))-1

3 结语

以上是所有内容,希望对大家有所帮助。

最近刷题速度明显下降

所以感觉时间远远不够用了

因此我找到了一个bug。

但这种方法只限于解决静态题目。

就是结果一成不变的题目。

比如说下面这个题目

1.三色球分组
从3个红球,5个白球,6个黑球中任意取出8个作为一组进行输出。在每组中可以没有黑球,但必须要有红球和白球。编程实现以上功能。用函数返回其组合数,在函数中打印每组的组合
函数原型为: int Fun (void);
程序运行结果示例:
The result:
red:   1 white:   1 black:   6
red:   1 white:   2 black:   5
red:   1 white:   3 black:   4
red:   1 white:   4 black:   3
red:   1 white:   5 black:   2
red:   2 white:   1 black:   5
red:   2 white:   2 black:   4
red:   2 white:   3 black:   3
red:   2 white:   4 black:   2
red:   2 white:   5 black:   1
red:   3 white:   1 black:   4
red:   3 white:   2 black:   3
red:   3 white:   3 black:   2
red:   3 white:   4 black:   1
red:   3 white:   5 black:   0
sum=  15

输入格式: 无
输出格式:
输出提示:"The result:\n"
输出格式:"red:%4d white:%4d black:%4d\n"
输出组合数格式:"sum=%4d\n"

贴上我的代码

#include<stdio.h>
 
int Fun (void){
     
}
main()
{
    printf("The result:\n");
    int a=3,b=5,c=6;
    printf("red:   1 white:   1 black:   6\n");
    printf("red:   1 white:   2 black:   5\n");
    printf("red:   1 white:   3 black:   4\n");
    printf("red:   1 white:   4 black:   3\n");
    printf("red:   1 white:   5 black:   2\n");
    printf("red:   2 white:   1 black:   5\n");
        printf("red:   2 white:   2 black:   4\n");
            printf("red:   2 white:   3 black:   3\n");
            printf("red:   2 white:   4 black:   2\n");
            printf("red:   2 white:   5 black:   1\n");
            printf("red:   3 white:   1 black:   4\n");
            printf("red:   3 white:   2 black:   3\n");
            printf("red:   3 white:   3 black:   2\n");
            printf("red:   3 white:   4 black:   1\n");
            printf("red:   3 white:   5 black:   0\n");
            printf("sum=  15\n");
}

其实就是把结果打印出来;

评分系统取测试结果分;虽然语义匹配分为0;

但是没关系;

我依旧拿到了满分hhhhh

个人不怎么推荐这种方法

除非你真的觉得这道题不想做了

附上这道题的正确代码

#include <stdio.h>
int Fun(void);
int main()
{                    
    int sum;
    sum = Fun();
    printf("sum=%4d\n", sum);
    return 0;
}                    
 
int Fun(void)
{                    
    int i, j, k, sum = 0;
    printf("The result:\n");
    for (i = 1; i <= 3; i++)
    {                    
        for (j = 1; j <= 5; j++)
        {                    
            for (k = 0; k <= 6; k++)
            {                    
                if (i + j + k == 8)
                {                    
                    printf("red:%4d white:%4d black:%4d\n", i, j, k);
                    sum = sum + 1;
                }
            }
        }
    }
    return sum;
}           

C语言学习五

今天早上又刷了一早上的题

本周练习为啥还有18个???

我表示极大的纳闷。。。

难度较低的题已经被我刷光了,可能难题刷的比较慢吧。

仅存的慰藉是我已经刷到了1810分,今天加加油,看能不能全刷完上2000分(要求全部的18道题都做对),但我感觉压力山大!!!

 

向着2500分的目标迈进;

如果可能,争取刷到3000分,拿到3分的加分!

废话不多说了!上代码!!!


PART .1

1.用递归方法编程计算输出Fibonacci数列,同时打印出计算Fibonacci数列每一项时所需的递归调用次数。
**输入格式要求:"%d" 提示信息:"Input n:"
**输出格式要求:"Fib(%d)=%d, count=%d\n"
程序运行示例如下:
Input n:10
Fib(1)=1, count=1
Fib(2)=1, count=3
Fib(3)=2, count=5
Fib(4)=3, count=9
Fib(5)=5, count=15
Fib(6)=8, count=25
Fib(7)=13, count=41
Fib(8)=21, count=67
Fib(9)=34, count=109
Fib(10)=55, count=177

 

先上我的垃圾错误代码

 

#include<stdio.h>
fib(a);
extern int c=0;
main()
{
    printf("Input n:");
    int n,i,c;
    scanf("%d",&n);
    fib(n);
}
fib(a)
{
    c=0;
    if(a==1)
    {
        printf("Fib(%d)=%d, count=%d\n",a,1,1);
        return 1;
    }
    if(a==2)
    {
        printf("Fib(%d)=%d, count=%d\n",a,2,3);
        return 1;
    }
    else
    {
    c++;
    printf("Fib(%d)=%d, count=%d\n",a,fib(a-1)+fib(a-2),c);
    }
}

其实这道题的计算原理都不难,很轻松的就想出来了。

难的地方就在与输出格式还有c的计算。(吐槽一下——格式真的好烦人)

懒得查答案了,反正金币一大堆,不如直接花10金币看答案

#include <stdio.h>
long Fib(int a);
int count;     /*全局变量count用于累计递归函数被调用的次数,自动初始化为0*/
int main()
{                        
    int n, i, x;
    printf("Input n:");
    scanf("%d", &n);
    for (i = 1; i <= n; i++)
    {                        
        count = 0;   /* 计算下一项Fibonacci数列时将计数器count清零 */
        x = Fib(i);
        printf("Fib(%d)=%d, count=%d\n", i, x, count);
    }
    return 0;
}                        
/* 函数功能:用递归法计算Fibonacci数列中的第n项的值 */
long Fib(int n)
{                        
    long f;
    count++;      /* 累计递归函数被调用的次数,记录于全局变量count中 */
    if (n == 0)   f = 0;
    else if (n == 1)   f = 1;
    else   f = Fib(n - 1) + Fib(n - 2);
    return f;
}                 
 

PART .2

编写函数在return 值的时候,笔者总是希望return 多个值。

然而C语言不允许;

询问Kai大佬后大佬说用Struct   然而小白还没学到结构体怎么办???

于是便想到了下面的一些方法(参考链接):

1.利用全局变量


  分析:全局变量作为C语言的一个知识点,虽然我们都了解它的特点,但在实际教学过程中应用得并不是很多。由于全局变量的作用域是从定义变量开始直到程序结束,而对于编写有多个返回值的C语言函数,我们可以考虑把要返回的多个值定义成全局变量。当函数被调用时,全局变量被更改,我们再把更改后的全局变量值应用于主调函数中。函数被调用后被更改后的全局变量值即为函数的数个返回值。下面以一个实例演示该方法的应用。
  实例1:编写函数求3个数中的最大值与最小值。
  方法:把最大值、最小值分别定义成2个全局变量max、min,在用户自定义函数中把求出来的最大值与最小值分别赋给全局变量max、min。函数调用完毕后全局变量的max、min值即保存了函数要求返回的值。程序参考代码如下:

  #include "stdio.h"
  #include "conio.h"
  int max,min;/*定义两个全局变量用于保存函数返回值*/
  void max_min(int a,int b,int c) /*定义求最大最小值的函数*/
  {max=min=a; /*初始化最大最小值*/
   if(max   if(max   if(min>b)min=b;
  if(min>c)min=c;
  }
  main()
  {int x,y,z;
  printf(" 请输入3个整数:\n");
  scanf("%d,%d,%d",&x,&y,&z);
  max_min(x,y,z) ;/*调用求最大值与最小值的函数*/
  printf("三个数中的最大值为:%d;最小值为:%d",max,min);/*输出最大值与最小值*/
  getch();
  }         

  调试结果如下:

  请输入3个整数:
  5,-6,2
  三个数中的最大值为:5;最小值为:-6


  注意:该方法虽然可以实现有多个返回值的函数,但由于全局变量不能保证值的正确性(因为其作用域是全局,所以程序范围内都可以修改它的值,如果出现错误将非常难以发现),并且全局变量增加了程序间模块的耦合,所以该方法要慎用。


2.传递数组指针
  
  分析:在教学过程中,我们知道C语言函数参数的传递方式有值传递与地址传递。当进行值传递时,主调函数把实参的值复制给形参,形参获得从主调函数传递过来的值运行函数。在值传递过程中被调函数参数值的更改不能导致实参值的更改。而如果是地址传递,由于传递过程中从实参传递过来的是地址,所以被调函数中形参值的更改会直接导致实参值的更改。因此,我们可以考虑把多个返回值作为数组元素定义成一个数组的形式,并使该数组的地址作为函数的形式参数,以传址方式传递数组参数。函数被调用后,形参数组元素改变导致实参改变,我们再从改变后的实参数组元素中获得函数的多个返回值。以下实例演示该方法的应用。
  实例2:编写函数求一维整形数组的最大值与最小值,并把最大值与最小值返回给主调函数。
  方法:以指针方式传递该一维数组的地址,然后把数组的最大值与数组的第一个元素交换,把数组的最小值与最后一个元素交换。函数被调用完毕后,实参数组中的第一元素为数组的最大值,实参数组中最后一个元素为数组的最小值,从而实现返回数组的最大值与最小值的功能。程序参考代码如下:

  #include "stdio.h"
  #include "conio.h"
  void max_min(int *ptr,int n) /*定义求数组最大值最小值的函数,传递数组指针*/
  {int i,j,k;/*j保存最大值所在位置,k保存最小值所在位置*/
  int *temp;/*用于交换位置*/
  *temp=*ptr;
  for(i=0;i  {
  if(*ptr<*(ptr+i))/*最大值与第一个元素进行交换*/
  {
  k=i;
  *temp=*ptr;
  *ptr=*(ptr+k);
  *(ptr+k)=*temp ;
  }
  if(*(ptr+n-1)>*(ptr+i))/*最小值与最后一个元素进行交换*/
  {
  j=i;
  *temp =*(ptr+n-1);
  *(ptr+n-1)=*(ptr+j);
  *(ptr+j)= *temp ;}
  }
  }
  /*调用最大最小值函数*/
  main()
  {
  int A[6],i;
  for(i=0;i<6;i++)
   scanf("%d",&A[i]);
  max_min(A,6);
  printf("max=%d, min=%d\n \n",A[0],A[5]);
  getch();
  }


  调试结果如下:
  请输入6个整形数,以空格隔开:
  5 8 9 32 -6 4
  max=32,min=-6

注意:该方法适用于多个返回值的数据类型一致的情况。当返回值数据类型不一致时,不适用该方法。
  
3.传递结构体指针
  
  分析:结构体作为教学中的一个难点,教材对它介绍的内容并不多,应用的实例更是少之又少,所以学生对于结构体普遍掌握情况不理想。其实,编写返回多个值的C语言函数,也可以考虑采用结构体的方式去实现。通过方法2,我们知道如果返回的数个数值的数据类型不一致,可以通过定义全局变量实现有多个返回值的C语言函数,也可以考虑把要求返回的数个值定义成一个结构体,然后同样以传递结构体指针方式把结构体的指针传递给形参结构体指针,那么函数中对形参结构体的修改即是对实参结构体的修改,函数被调用后获取的实参结构体成员即为函数的多个返回值,下面以实例演示该方法的应用。
  实例3:编写一个用户自定义函数,允许用户录入学生的基本信息(包括学号、姓名、所属班级、总评成绩),并返回这些基本信息给主调函数。
  
  方法:把学生基本信息定义成一个结构体,在用户自定义函数中传递该结构体的指针,则自定义函数中对结构体成员的录入操作即是对实参结构体成员的录入操作,从而实现多个返回值。参考代码如下:

  #include "stdio.h"
  #include "conio.h"
  struct inf{/*定义学生结构体,分别包含成员学号、姓名、班别、总评成绩*/
   char xh[12];
   char name[20];
   char class[15];
   int chj;
  };
  main(void)
  {
  struct inf a1; /*定义学生结构体类型变量*/
  void xxxx(struct inf *ptr);
  printf("请输入学号,姓名,班别,总评成绩,以空格隔开:\n") ;
  xxxx(&a1);/*调用函数,以学生结构体类型变量地址作为实参*/
  printf("学号:%s,姓名: %s,班别:%s,总评成绩:%d",a1.xh, a1.name,a1.class,a1.chj);
  getch();
  }
  void xxxx(struct inf *ptr)/*该函数实现对结构体成员数据的录入操作*/
  {
   char xh1[12],name1[20],class1[15];
   int chj1;
  scanf("%s%s%s%d",xh1,name1,class1,&chj1);
   strcpy(ptr->xh,xh1);
  strcpy(ptr->name,name1);
  strcpy(ptr->class,class1);
  ptr->chj=chj1;
   }


  调试结果如下:
  请输入学号,姓名,班别,总评成绩,以空格隔开:
  200102LiLi200185
  学号:200102,姓名: LiLi,班别:2001,总评成绩:85
  注意:当函数要求返回的多个值是相互联系的或者返回的多个值数据类型不一致时可以采用该方法。
  
4.结束语
  对于以上这三种方法,如果想要返回的数个值数据类型一致,可以考虑采用方法2;而对于不同数据类型的返回值,如果各个数值之间是相互联系的,则方法3较为合适;方法1虽然在很多情况下都可以实现多个返回值的C语言函数,但毕竟全局变量应用过程中有很多危险,要慎重使用。
  通过对以上几种方法的分析讲解,在教学过程中,学生再遇到这样的问题时,就能根据返回值的情况选择合适的途径去实现多个返回值的C语言函数。另外,如果再遇到类似的无法用教材知识点去直接解决的问题时,他们基本都能举一反三地尝试采用间接方式去解决。

C语言学习四

C语言中main函数return的总结

在函数中,如果碰到return 语句,那么程序就会返回调用该函数的下一条语句执行,也就是说跳出函数的执行,回到原来的地方继续执行下去。但是如果是在主函数中碰到return语句,那么整个程序就会停止,退出程序的执行。

return是C++预定义的语句,它提供了种植函数执行的一种放大。当return语句提供了一个值时,这个值就成为函数的返回值.

说到return,有必要提及主函数的定义,下面是从网络上找到的资料,好好消化吧,对了解主函数中返回值的理解有很大的帮助.

很多人甚至市面上的一些书籍,都使用了void main( ) ,其实这是错误的。C/C++ 中从来没有定义过void main( ) 。C++ 之父 Bjarne Stroustrup 在他的主页上的 FAQ 中明确地写着 The definition void main( ) { /* ... */ } is not and never has been C++, nor has it even been C.( void main( ) 从来就不存在于 C++ 或者 C )。下面我分别说一下 C 和 C++ 标准中对 main 函数的定义。


1. C
在 C89 中,main( ) 是可以接受的。Brian W. Kernighan 和 Dennis M. Ritchie 的经典巨著 The C programming Language 2e(《C 程序设计语言第二版》)用的就是 main( )。不过在最新的 C99 标准中,只有以下两种定义方式是正确的:
int main( void )
int main( int argc, char *argv[] )
(参考资料:ISO/IEC 9899:1999 (E) Programming languages — C 5.1.2.2.1 Program startup)
当然,我们也可以做一点小小的改动。例如:char *argv[] 可以写成 char **argv;argv 和 argc 可以改成别的变量名(如 intval 和 charval),不过一定要符合变量的命名规则。

如果不需要从命令行中获取参数,请用int main(void) ;否则请用int main( int argc, char *argv[] ) 。
main 函数的返回值类型必须是 int ,这样返回值才能传递给程序的激活者(如操作系统)。

如果 main 函数的最后没有写 return 语句的话,C99 规定编译器要自动在生成的目标文件中(如 exe 文件)加入return 0; ,表示程序正常退出。不过,我还是建议你最好在main函数的最后加上return 语句,虽然没有这个必要,但这是一个好的习惯。注意,vc6不会在目标文件中加入return 0; ,大概是因为 vc6 是 98 年的产品,所以才不支持这个特性。现在明白我为什么建议你最好加上 return 语句了吧!不过,gcc3.2(Linux 下的 C 编译器)会在生成的目标文件中加入 return 0; 。

2. C++
C++98 中定义了如下两种 main 函数的定义方式:
int main( )
int main( int argc, char *argv[] )
(参考资料:ISO/IEC 14882(1998-9-01)Programming languages — C++ 3.6 Start and termination)
int main( ) 等同于 C99 中的 int main( void ) ;int main( int argc, char *argv[] ) 的用法也和 C99 中定义的一样。同样,main 函数的返回值类型也必须是int。如果main函数的末尾没写return语句,C++98 规定编译器要自动在生成的目标文件中加入 return 0; 。同样,vc6 也不支持这个特性,但是 g++3.2(Linux 下的 C++ 编译器)支持。

3. 关于 void main
在 C 和 C++ 中,不接收任何参数也不返回任何信息的函数原型为“void foo(void);”。可能正是因为这个,所以很多人都误认为如果不需要程序返回值时可以把main函数定义成void main(void) 。然而这是错误的!main 函数的返回值应该定义为 int 类型,C 和 C++ 标准中都是这样规定的。虽然在一些编译器中,void main 可以通过编译(如 vc6),但并非所有编译器都支持 void main ,因为标准中从来没有定义过 void main 。g++3.2 中如果 main 函数的返回值不是 int 类型,就根本通不过编译。而 gcc3.2 则会发出警告。所以,如果你想你的程序拥有很好的可移植性,请一定要用 int main 。

4. 返回值的作用
main 函数的返回值用于说明程序的退出状态。如果返回 0,则代表程序正常退出,否则代表程序异常退出。下面我们在 winxp 环境下做一个小实验。首先编译下面的程序:
int main( void )
{
return 0;
}
然后打开附件里的“命令提示符”,在命令行里运行刚才编译好的可执行文件,然后输入“echo %ERRORLEVEL%”,回车,就可以看到程序的返回值为 0 。假设刚才编译好的文件是 a.exe ,如果输入“a && dir”,则会列出当前目录下的文件夹和文件。但是如果改成“return -1”,或者别的非 0 值,重新编译后输入“a && dir”,则 dir 不会执行。因为 && 的含义是:如果 && 前面的程序正常退出,则继续执行 && 后面的程序,否则不执行。也就是说,利用程序的返回值,我们可以控制要不要执行下一个程序。这就是 int main 的好处。 如果你有兴趣,也可以把 main 函数的返回值类型改成非 int 类型(如 float),重新编译后执行“a && dir”,看看会出现什么情况,想想为什么会出现那样的情况。顺便提一下,如果输入 a || dir 的话,则表示如果 a 异常退出,则执行 dir 。


5. 那么 int main(intargc,char*argv[],char*envp[])呢?
  这当然也不是标准 C 里面定义的东西!char*envp[] 是某些编译器提供的扩展功能,用于获取系统的环境变量。因为不是标准,所以并非所有编译器都支持,故而移植性差,不推荐使用。
到了这里,你应该了解为什么主函数定义为 int返回类型,而且函数体里面有return 0;这个语句了吧.
下面具体说说我对return的应用的理解。

只要一个函数的返回值是数字型的,那么就可以返回0(即return 0),其实你返回多少都没问题。一 般情况下,C++做出来的函数都要求返回一个值,当函数执行正常,且达到了一般情况下的目的,那么就返回0表示正确的调用了该函数,这个0就是返回给主调 函数以通知没有出错的;如果函数调用中出错,或者没有按照一般情况执行,那么就返回1,以告知主调函数采取响应策略;如果你在某个函数所在类的定义所在的 头文件中定义了一组状态值(一般都是负整数),那么函数就可以返回不同的值以告之主调函数具体发生了什么异常或错误,这种情况一般用于函数功能独立性较差 的的情况。所以一般不鼓励把函数返回类型定义为void,至少返回应该是int,而在函数的最后加上return 0.语句:
int func(参数列表)
{
……
……
……
Return 0;
}
在函数中,如果碰到return 语句,那么程序就会返回调用该函数的下一条语句执行,也就是说跳出函数的执行,回到原来的地方继续执行下去。但是如果是在主函数中碰到return语句,那么整个程序就会停止,退出程序的执行。
如果你定义一个函数有返回类型,可以想下面那样调用:
int func()
{
int value;
……
……
……
return value;
}
int main()
{
int intvalue;
intvalue=func();
……
……
teturn 0;
}


return语句后面具体是什么内容,这就要具体情况具体分析了:
(1) 在返回类型是char的函数中,return后应该是char类型的值;
(2) 在返回类型是int的函数中,如果是要停止函数的调用,最好应该为0;其他的按照你的目的而定,只要是int 类型就行了
(3) 在返回类型是结构类型的函数中,return后应该是结构的一个实例对象。
总之,函数定义为什么样的返回类型,该函数中return后就应该是相应类型的值。

C语言学习三

二元一次方程解法

#include<stdio.h>
#include<math.h>
#define eps 1e-6
main()
{
    float a,b,c,d;
    printf("Please enter the coefficients a,b,c:");
    scanf("%f,%f,%f",&a,&b,&c);
    if(a==0)
    printf("It is not a quadratic equation!\n");
    else
    {
        d=sqrt(fabs(b*b-4*a*c));
        if(fabs(b*b-4*a*c)<eps)
        printf("x1 = x2 = %.2f\n",(-b+d)/2/a);
        else if(b*b-4*a*c>eps)
        printf("x1 = %.2f, x2 = %.2f\n",(-b+d)/2/a,(-b-d)/2/a);
        else
        printf("x1 = %.2f+%.2fi, x2 = %.2f-%.2fi\n",-b/2/a ,d/2/a ,-b/2/a ,-d/2/a);
    }
}

注意:在这个程序中,最好不要用pow函数

因为:pow是有精度损失的

          计算机没这么聪明,能判断出你的是int型pow,计算机全部当double处理了

pow(2,2) = 3.999999999
pow(2,2) + 0.05 = 4.0499999
然后强制转化就会成为4了

eg

for(i=1;i<=  (int)(pow(m,1.0/3)+0.05); i++)

附上第一次的麻烦代码:

#include<stdio.h>
#include<math.h>
#define   EPS 1e-6
#include "windows.h"
main()
{
    float a,b,c;
    float d;
    printf("Please enter the coefficients a,b,c:");
    scanf("%f,%f,%f",&a,&b,&c);
    d=sqrt(b*b-4*a*c);
    if(a==0)
    printf("It is not a quadratic equation!\n");
    else{
    if(b*b-4*a*c==0)
    printf("x1 = x2 = %.2f\n",(-b+d)/(2*a));
    else if(b*b-4*a*c>0)
    printf("x1 = %.2f, x2 = %.2f\n",(-b+d)/(2*a),(-b-d)/(2*a));
    else
    printf("x1 = %.2f+%.2fi, "  "x2 = %.2f-%.2fi\n",-b/(2*a),sqrt(fabs(b*b-4*a*c))/(2*a),-b/(2*a),sqrt(fabs(b*b-4*a*c))/(2*a));
         
    }


 

C语言学习二

1.

亲密数_1
2500年前数学大师毕达哥拉斯就发现,220与284两数之间存在着奇妙的联系:
220的真因数之和为:1+2+4+5+10+11+20+22+44+55+110=284
284的真因数之和为:1+2+4+71+142=220
毕达哥拉斯把这样的数对称为相亲数。

相亲数,也称为亲密数,如果整数A的全部因子(包括1,不包括A本身)之和等于B,且整数B的全部因子(包括1,不包括B本身)之和等于A,则将整数A和B称为亲密数。
从键盘任意输入两个整数m和n,编程判断m和n是否是亲密数。若是亲密数,则输出“Yes!”,否则输出“No!”

程序运行示例1
Input m, n:
220,284↙
Yes!

程序运行示例2Input m, n:
224,280↙
No!

输入格式: "%d,%d"
输出格式:
输入提示信息:"Input m, n:\n"
输出提示信息:"Yes!\n"
              "No!\n"

 

#include<stdio.h>
judgeclose(a,b);
main()
{
    printf("Input m, n:\n");
    int m,n;
    scanf("%d,%d",&m,&n);
    if(judgeclose(m,n)==1)
    printf("Yes!\n");
    else
    printf("No!\n");
}
judgeclose(a,b)
{
    int i,j,k=0;
    int s[20]={0},t[20]={0},e[20]={0},f[20]={0};
    for(i=1;i<=a;i++)
        for(j=2;j<a;j++)
        {
            if (i*j==a)
            {
            s[k]=i;
            t[k]=j;
            k++;
            }
        }
     for(i=1;i<=b;i++)
        for(j=2;j<b;j++)
        {
            if (i*j==b)
            {
            e[k]=i,f[k]=j;
            k++;
            }
        }
        int s1=0,s2=0;
    for(i=0;i<20;i++)
    {
        s1+=s[i]+t[i];
        s2+=e[i]+f[i];
    }
   s1=s1/2+1;
   s2=s2/2+1;
    if(s1==b&&s2==a)
        return 1;
    else return 0;
}

看我写的这串垃圾代码。。。

要是考试肯定半个小时构思+写肯定写不完。。。

再看看同一类型题大神的方法:

2.

链接)一个数对(x,y)是亲和数对,当且仅当 x 的非自身的因数之和等于 y,且 y 的非自身的因数之和等于 x。如果(x,y)是亲和数对,那么认为(y,x)是与之相同的亲和数对。若 A<=x<=B,则称亲和数对(x,y)在[A,B]范围内。现输入范围 A 和 B,求 [A,B] 内所有亲和数对个数。例如 [200,1200] 内有两个亲和数对 (220,284) 和 (1184,1210),因为 220 的非自身因数和 1+2+4+5+10+11+20+22+44+55+110=284,284 的非自身因数之和为 1+2+4+71+142=220。
解一:解法骨架是枚举 [A,B] 范围内所有 x,算出 x 的非自身正因数之和 y(y < x),若 y 的非自身因数之和为 x,则代表找到了一个亲和数对。于是得到了一个直观的朴素解法。
解二:但显然上述解法效率过低。为了避免重复计算,我们创建一个 res[x] 数组保存 x 的因子和。于是得到了比解一快得多的解法。
解三:但是上述解法仍然太慢。问题在哪里?容易知道,时间主要耗费在了计算因子上(% 和 / 是同一个CPU指令,耗费时间相同)。我们不妨换一种思维方式,枚举因子 i,并把因子 i 加到 res[i*j] 里面,当枚举结束时,res[x] 就是 x 的因子和。这个方法快在两个方面:(1)机器算乘法本来就比除法快;(2)没有多余的整除判断。于是我们得到了最快的解法,并且代码比上面两种解法更为简洁。下面的代码利用了全局变量默认为空,没有 memset(res, 0, sizeof res)。

#include <stdio.h>
int res[100000005];
int main() {
  int A, B, ans=0;
  scanf("%d%d", &A, &B);
  for(int i = 1; i <= B; ++i)
    for(int j = 2; i*j <= 2*B; ++j)
      res[i*j] += i;
  for(int x = A; x <= B; ++x)
    if(res[x] > x && res[res[x]] == x) ++ans;
  printf("%d\n", ans);
  return 0;
}

需要说明的是

(要运行这个程序,我们需要在C99并添加新的头文件或C++编译器下进行!)

于是差距就出现了:手动滑稽hhh

Plus:C++真的比C语言简便好多啊

From:Kai

3.

完全数
完全数(Perfect Number),又称完美数或完数,它是指这样的一些特殊的自然数。它所有的真因子(即除了自身以外的约数)的和,恰好等于它本身,即m的所有小于m的不同因子(包括1)加起来恰好等于m本身。注意:1没有真因子,所以1不是完全数。计算机已经证实在10300以下,没有奇数的完全数。例如,因为6 = 1 + 2 + 3,所以6是一个完全数。
从键盘任意输入一个整数m,编程判断m是否是完全数。若m是完全数,则输出“Yes!”,并同时打印出每一个完美数的全部因子,以验证这个数确实是一个完美数。若m不是完全数,则输出“No!”
程序运行示例1
Input m:
28↙
Yes!
1,2,4,7,14

程序运行示例2
Input m:
6↙
Yes!
1,2,3

程序运行示例3
Input m:
1↙
No!

输入信息提示:"Input m:\n"
输入格式: "%d"

输出格式: "%d"
输出因子时用逗号间隔,格式为:  ","
判断是完全数,输出信息提示:"Yes!\n"
判断不是完全数,输出信息提示: "No!\n"

//有了上一道题作为基础,这道题就显得很简单了//

#include<stdio.h>
judgetrue(a);
main()
{
    printf("Input m:\n");
    int m;
    scanf("%d",&m);
    judgetrue(m);
}
judgetrue(a)
{
    int i,j,k=0;
    int s[20]={0},t[20]={0};
    for(i=1;i<=a;i++)
        for(j=2;j<=a;j++)
        {
            if (i*j==a)
            {
            s[k]=i;
            t[k]=j;
            k++;
            }
        }
    int s1=0;
    for(i=0;i<20;i++)
    {
        s1+=s[i];
    }
    if(s1==a)
    {
        printf("Yes!\n");
        for(i=0;i<20;i++)
        {
            if(s[i]!=0)
           {
               printf("%d",s[i]);
               if(s[i+1]!=0)
                printf(",");

           }
        }

    }
    else
    printf("No!\n");
}

4.

五个水手在岛上发现一堆椰子,先由第1个水手把椰子分为等量的5堆,还剩下1个给了猴子,自己藏起1堆。然后,第2个水手把剩下的4堆混合后重新分为等量的5堆,还剩下1个给了猴子,自己藏起1堆。以后第3、4个水手依次按此方法处理。最后,第5个水手把剩下的椰子分为等量的5堆后,同样剩下1个给了猴子。请用迭代法编程计算并输出原来这堆椰子至少有多少个。
**输出格式要求:"y = %d\n"

#include "stdio.h"
int can(int k)
{
   int i;
   for (i=1;i<=5;i++)
   {
       if ((k-1)%5!=0||k<  5) return 0;
       k=(k-1)/5*4;
   }
   return 1;
}
int main()
{
   int ans=1;
   while (!can(ans)) ans++;
   printf("y = %d\n",ans);

   return 0;
}

5.求1000内的

#include<stdio.h>
#define m 1000
judgetrue(a);
main()
{
    int i;
    for(i=2;i<=m;i++)
    judgetrue(i);
}
judgetrue(a)
{
    int i,j,k=0;
    int s[100]={0};
    for(i=1;i<=a;i++)
        for(j=2;j<=a;j++)
        {
            if (i*j==a)
            {
            s[k]=i;
            k++;
            }
        }
    int s1=0;
    for(i=0;i<100;i++)
    {
        s1+=s[i];
    }
    if(s1==a)
    {
        printf("\n%5d\n",s1);
        for(i=0;i<20;i++)
        {
            if(s[i]!=0)
           {
               printf("%5d",s[i]);
           }
        }

    }
    else;
}

你可以发现:我每个程序都是在原程序的基础上进行修改而成的。

所以我把这些程序上传在了这个博客上,以备后事之需。

C语言练习一

1.

奥运参赛国出场次序:
输入奥运会参赛国国名,并按照字典序对其进行排序。
要求:参赛国数量不超过150个,每个国家的名字不超过9个字符。
提示:‘\0’占一个字符。

#include <string.h>
#include <stdio.h>
#define N 151
#define MAX_LEN 10
void SortString(char str[][MAX_LEN], int n);

int main()
{
    int i, n;
    char name[N][MAX_LEN];
    printf("How many countries?");
    scanf("%d",&n);
    getchar();
    printf("Input their names\n");

    for(i=0;i<n;i++)
        gets(name[i]);

    SortString(name, n);
    printf("Sorted results:\n");
    for(i=0;i<n;i++)
    {
        puts(name[i]);
    }
    return 0;

}

void SortString(char str[][MAX_LEN], int n)
{
    int i,j;
    char temp[MAX_LEN];

    for(i=0;i<n;i++)
    {
        for(j=i+1;j<n;j++)
        {
            if(strcmp(str[j],str[i])<0)
            {
                strcpy(temp,str[i]);
                strcpy(str[i],str[j]);
                strcpy(str[j],temp);
            }
        }
    }
}

2.

统计正整数中指定数字的个数
从键盘输入一个正整数number,求其中含有指定数字digit的个数。例如:从键盘输入正整数number=1222,若digit=2,则1223中含有 3个2,要求用函数实现。
函数原型为:int CountDigit(int number,int digit);

程序运行结果示例1:
Input m,n:
1222,2↙
3

程序运行结果示例2:
Input m,n:
1234,6↙
0

输入格式: "%d,%d"
输出格式:
输入提示信息:"Input m,n:\n"
输出格式:"%d\n"

#include<stdio.h>
int CountDigit(int number,int digit);
main()
{
    printf("Input m,n:\n");
    int m,n;
    scanf("%d,%d",&m,&n);
    printf("%d\n",CountDigit(m,n));
}
int CountDigit(int number,int digit)
{
    int c=0;
    while(number)
    {
        if(digit==number%10)
        {c++;
        number=number/10;
        }
    }
    return c;
}

3.冒泡程序

#include<stdio.h>
#define LEN 10
void bubble(int dat[], int length);
main( )
{
    int  data[LEN]={0}, i;
    for (i=0; i<= LEN-1; i++)
    {
        scanf("%d",&data[i]);
    }
    bubble(data,LEN);
    for(i=0; i<= LEN-1; i++)     
        {
            printf("%8d", data[i]);
        }
}
void bubble(int dat[], int length)
{
        int head, tail,round,i;
        int t;
        head = 0;
        tail = length - 1;
 
    for (round = head; round <= tail; round++)
        for (i = tail; i >= round+1; i--)
            if ( dat[i] < dat[i-1] )
            {
                t=dat[i];             
                dat[i]=dat[i-1];
                dat[i-1]=t;
            }
}

4.实验题

编写程序统计从键盘输入的一行文本中各个字母的个数。
输入以回车键结束。
不区分大小写,大写字母与相应的小写字母按照同一个字母看待。
要求输出按照各个字母出现的个数从大到小进行排序,出现的个数相同的,按照字母在字母表中的先后顺序进行排序。
***输入格式:调用getchar()函数依次输入每个字符
***输出格式:"%c(%c):%d\n"
例如输入以下文本:
Hello World
程序将输出:
L(l):3
O(o):2
D(d):1
E(e):1
H(h):1
R(r):1
W(w):1
A(a):0
B(b):0
C(c):0
F(f):0
G(g):0
I(i):0
J(j):0
K(k):0
M(m):0
N(n):0
P(p):0
Q(q):0
S(s):0
T(t):0
U(u):0
V(v):0
X(x):0
Y(y):0
Z(z):0

#include <stdio.h>
#include<stdlib.h>
void bubble_sort(int a[], int c[],int n);
int main(void)
{int i;
int c[27]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
 char j;
 char a;                                       
 int b[26]={0};                      
 int count[26]={0};
 while ((a = getchar()) != '\n')     
   {
   for (j='A';j<='Z';++j)               
       {
           if (a == j || a == j+32)
           {
               b[j-'A']++;count[j-'A']++;
           }
   
       }
   }
   bubble_sort(b,c,26);
   for (i=0;i<26;++i)
   {
        printf("%c(%c):%d\n",c[i]-32,c[i],b[i]);
           
   }
}
    
void bubble_sort(int a[],int c[], int n)
{
    int i, j, temp;
    for (j = 0; j < n - 1; j++)
        for (i = 0; i < n - 1 - j; i++)
        {
            if(a[i] < a[i + 1])
            {
                temp = a[i];
                a[i] = a[i + 1];
                a[i + 1] = temp;
                temp = c[i];
                c[i] = c[i + 1];
                c[i + 1] = temp;
            }
        }
}

这道题是我做过后觉得比较难的,可能算法并不是很简便,如果各位大神有什么好的方法请一定告诉我。