温馨提示
:本文章长达五万字,可以在网盘或github中下载源码后对照观看。
网盘链接
:https://pan.imtwa.top/s/YovtAJK1h9github地址
:https://github.com/imtwa/c-Problem-100
网盘内有文章的html和md文件,可下载后保存在本地查阅。
文章已经同步在CSDN,传送链接:https://blog.csdn.net/qq_60724861/article/details/135554446
前言
这是在2023年12月突然萌生的一个想法,“使用各种编程语言实现经典100题”,目前准备实现c语言 c++ java python四种语言的代码编写,现在是2024年1月12日,让我们开始吧!
001:无重复的三位数
题目
有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
思路
这道题简单的做法就是使用三个循环,在最内层循环判断是否重复,不重复就打印出来。当然也能看成一个变种全排列问题,dfs深度优先搜索算法写一个简单模板就可以解决全排列问题。c++的算法库里也有全排列的函数。如果dfs不想多开数组就使用java中的方法,直接修改数组。
代码实现
C语言
c
/*
题目
有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
*/
#include <stdio.h>
int p[4] = {1,2,3,4};
int a[4],visit[4];
int n = 4,z = 0;
void dfs(int s) {
int i;
// 打印
if(s==n) {
for(i=0; i<n-1; i++) {
printf("%d ",a[i]);
}
printf("\n");
z++;
return;
}
//递归调用
for(i=0; i<n; i++) {
// 如果这个位置没有用过
if(!visit[i]) {
visit[i]=1;
// 赋值到a数组中
a[s]=p[i];
// 递归下一个位置
dfs(s+1);
// 递归结束释放该位置
visit[i]=0;
}
}
}
int main() {
int i, j, k;
// 使用dfs深度优先算法
// dfs(0);
// 使用三个变量作为下标 改变下标位置打印
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
for (k = 0; k < n; k++) {
if (p[i] != p[j] && p[i] != p[k] && p[j] != p[k]) {
printf("%d %d %d\n", p[i], p[j], p[k]);
z++;
}
}
}
}
printf("共有%d个",z);
return 0;
}
c++
/*
题目
有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
*/
#include <iostream>
#include <algorithm>
using namespace std;
int p[4] = {1,2,3,4};
int a[4],visit[4];
int n = 4,z = 0;
void dfs(int s) {
int i;
// 打印
if(s==n) {
for(i=0; i<n-1; i++) {
cout<<a[i]<<" ";
}
cout<<endl;
z++;
return;
}
//递归调用
for(i=0; i<n; i++) {
// 如果这个位置没有用过
if(!visit[i]) {
visit[i]=1;
// 赋值到a数组中
a[s]=p[i];
// 递归下一个位置
dfs(s+1);
// 递归结束释放该位置
visit[i]=0;
}
}
}
int main() {
// 调用dfs深度优先搜索算法
// dfs(0);
// 使用 algorithm算法库中的全排列函数
do {
cout<<p[0]<<" "<<p[1]<<" "<<p[2]<<endl;
z++;
} while(next_permutation(p,p+4));
cout<<"共有"<<z<<"个"<<endl;
return 0;
}
java
/*
* 题目
* 有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
* */
public class problem1 {
public static int z = 0;
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4};
dfs(arr, arr.length, 0);
System.out.println("共有" + z + "个");
}
/**
* 深度优先搜索算法,用于在数组中查找并交换元素
*
* @param arr 要搜索的数组
* @param size 数组的长度
* @param n 当前要处理的索引位置
*/
public static void dfs(int[] arr, int size, int n) {
if (n == size) {
System.out.println(arr[0] + " " + arr[1] + " " + arr[2]);
z++;
} else {
for (int i = n; i < size; i++) {
//两值不相等或要执行的是它本身,则需要交换
if (arr[i] != arr[n] || i == n) {
swap(arr, i, n);
dfs(arr, size, n + 1);
swap(arr, i, n);
}
}
}
}
/**
* 交换数组中指定位置的元素
*
* @param arr 要交换元素的数组
* @param i 要交换的第一个元素的位置
* @param j 要交换的第二个元素的位置
*/
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
python
# 题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
import itertools # 导入itertools模块,用于生成排列
s = [1, 2, 3, 4] # 初始化一个空列表
# 生成列表s的所有长度为n的排列,并将结果转换为列表
num = list(itertools.permutations(s, 4))
z = len(num)
# 遍历每个排列并打印
for ch in num:
# 遍历排列中的每个数字并打印
for i in range(3):
print(ch[i], end=' ') # 打印数字,并在数字之间添加空格(end参数指定了打印结束后的行为)
print() # 打印一个换行符,开始新的一行
print(f"共有 {z} 个排列")
002:计算利润
题目
企业发放的奖金根据利润提成。
利润(I)低于或等于10万元时,奖金可提10%;
利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%;
20万到40万之间时,高于20万元的部分,可提成5%;
40万到60万之间时高于40万元的部分,可提成3%;
60万到100万之间时,高于60万元的部分,可提成1.5%;
高于100万元时,超过100万元的部分按1%提成。
从键盘输入当月利润I,求应发放奖金总数?
思路
这道题很多解法都是直接if else或者switch,当然这道题是理解分支结构的一道好题目,只是代码写出来太不优雅了。我们完全可以开两个数组存放利润与奖金率,根据它们的对应关系使用循环实现题目。这里需要注意c++里格式化小数的方法。
代码实现
C语言
/*
题目:
企业发放的奖金根据利润提成。
利润(I)低于或等于10万元时,奖金可提10%;
利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%;
20万到40万之间时,高于20万元的部分,可提成5%;
40万到60万之间时高于40万元的部分,可提成3%;
60万到100万之间时,高于60万元的部分,可提成1.5%;
高于100万元时,超过100万元的部分按1%提成。
从键盘输入当月利润I,求应发放奖金总数?
*/
#include <stdio.h>
double calculate_bonus(double profit) {
double bonus = 0.0;
if (profit <= 10) {
bonus = profit * 0.1;
} else if (profit <= 20) {
bonus = 10 * 0.1 + (profit - 10) * 0.075;
} else if (profit <= 40) {
bonus = 10 * 0.1 + 10 * 0.075 + (profit - 20) * 0.05;
} else if (profit <= 60) {
bonus = 10 * 0.1 + 10 * 0.075 + 20 * 0.05 + (profit - 40) * 0.03;
} else if (profit <= 100) {
bonus = 10 * 0.1 + 10 * 0.075 + 20 * 0.05 + 20 * 0.03 + (profit - 60) * 0.015;
} else {
bonus = 10 * 0.1 + 10 * 0.075 + 20 * 0.05 + 20 * 0.03 + 40 * 0.015 + (profit - 100) * 0.01;
}
return bonus;
}
double calc(double profit) {
// 分级与奖金提成率
int p[10] = {0,10,20,40,60,100};
double b[10] = {0.1,0.075,0.05,0.03,0.015,0.01};
int i,k = 0;
double bonus = 0.0;
// 获得当前利润在哪个等级
for(i=0; i<6; i++) {
if(profit<=p[i])break;
}
k = i-1;
// 从高到最低计算提成
for(i=k; i>=0; i--) {
// 获取在每个等级的金额数
int z = profit - p[i];
// 计算该等级的提成
bonus += z*b[i];
// 减去上一等级内容
profit -= z;
}
return bonus;
}
int main() {
double profit;
printf("请输入当月利润:");
scanf("%lf", &profit);
// double bonus = calculate_bonus(profit);
double bonus = calc(profit);
printf("应发放奖金总数为:%.2lf\n", bonus);
return 0;
}
c++
/*
题目:
企业发放的奖金根据利润提成。
利润(I)低于或等于10万元时,奖金可提10%;
利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%;
20万到40万之间时,高于20万元的部分,可提成5%;
40万到60万之间时高于40万元的部分,可提成3%;
60万到100万之间时,高于60万元的部分,可提成1.5%;
高于100万元时,超过100万元的部分按1%提成。
从键盘输入当月利润I,求应发放奖金总数?
*/
#include <iostream>
#include <iomanip>
using namespace std;
double calc(double profit) {
// 分级与奖金提成率
int p[10] = {0,10,20,40,60,100};
double b[10] = {0.1,0.075,0.05,0.03,0.015,0.01};
int i,k = 0;
double bonus = 0.0;
// 获得当前利润在哪个等级
for(i=0; i<6; i++) {
if(profit<=p[i])break;
}
k = i-1;
// 从高到最低计算提成
for(i=k; i>=0; i--) {
// 获取在每个等级的金额数
int z = profit - p[i];
// 计算该等级的提成
bonus += z*b[i];
// 减去上一等级内容
profit -= z;
}
return bonus;
}
int main() {
double profit;
printf("请输入当月利润:");
cin>>profit;
double bonus = calc(profit);
cout<<"应发放奖金总数为:";
// cout << fixed; // 加上这句话固定两位小数 即 整数1也会打印成1.00
cout<<setprecision(2)<<bonus<<endl;
return 0;
}
003:完全平方数
题目
一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?
思路
这道题可以列公式计算,也可以通过int类型只保留整数的角度来解答,完全平方数开方后一定是一个整数,如果强转成Int和原先的值一样,则可以说明找到该数了。(1e+8为科学计数法,值为10^8)
代码实现
C语言
/*
题目:一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?
*/
#include <stdio.h>
#include <math.h>
int main() {
int i = -101;
double a = -1, b = -1;
while (i<1e+8) {
a = sqrt(i + 100);
b = sqrt(i + 100 + 168);
if (a == (int)a && b == (int)b) {
printf("%d\n", i);
}
i++;
}
return 0;
}
004:判断第几天
题目
输入某年某月某日,判断这一天是这一年的第几天?
思路
年份用来判断2月天数,其它月份1 3 5 7 10 12月为31天,最后加上几号即可。
代码实现
C语言
/*
题目:输入某年某月某日,判断这一天是这一年的第几天?
*/
#include <stdio.h>
int main() {
int i;
int n,x,y;
int z=0;
printf("请输入年份\n");
scanf("%d",&n);
printf("请输入月份\n");
scanf("%d",&x);
printf("请输入日期\n");
scanf("%d",&y);
for(i=1; i<x; i++) {
//计算2月的天数
if(i==2) {
if(n%400 == 0 || n%4 == 0 && n%100 != 0) {// 判断闰年
z+=29;
} else {
z+=28;
}
}
if(i==1||i==3||i==5||i==7||i==8||i==10||i==12) {
z+=31;
} else if(i!=2) {
z+=30;
}
}
z+=y;
printf("%d年%d月%d号,是该年的第%d天",n,x,y,z);
return 0;
}
005:由小到大输出(系统排序)
题目
输入三个整数x,y,z,把这三个数由小到大输出。
思路
只是三个数的话直接互相比较也可以,不过还是用自带的排序算法比较方便。这道题我们分别了解一下C语言 c++ java python等各种语言自带的排序怎么使用。了解冒泡 选择和插入排序请看第37题(对十个数的排序)。
代码实现
C语言
/*
题目:输入三个整数x,y,z,把这三个数由小到大输出。
*/
#include <stdio.h>
#include <stdlib.h>
void run(int x,int y,int z) {
int t;
if (x > y) {
t = x;
x = y;
y = t;
}
if (x > z) {
t = x;
x = z;
z = t;
}
if (y > z) {
t = y;
y = z;
z = t;
}
printf("%d %d %d", x, y, z);
}
int gg(const void* x,const void *y) {
//如果需要从大到小排序则写成return *(int *)y-*(int *)x;
return *(int *)x-*(int *)y;
}
int main() {
int p[10];
int i;
for(i=0; i<3; i++) {
scanf("%d",p+i);
}
// run(p[0],p[1],p[2]);
//自带排序函数 在头文件<stdlib.h>中
qsort(p,3,sizeof(p[0]),gg);
for(i=0; i<3; i++) {
printf("%d ",p[i]);
}
return 0;
}
006:输出字母C
题目
用*号输出字母C的图案。
思路
直接打印或者循环控制都可以
代码实现
C语言
/*
题目:用*号输出字母C的图案。
*/
#include<stdio.h>
void run() {
printf(" ***\n");
printf("*\n");
printf("*\n");
printf(" ***\n");
}
void run2() {
int i, j;
int n = 10; // 控制图案的大小
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
if (i == 0 || i == n - 1 || j == 0) {
printf("*"); // 打印边框
} else {
printf(" "); // 打印空格
}
}
printf("\n"); // 换行
}
}
int main() {
// run();
run2();
return 0;
}
007:输出国际象棋
题目
输出类似于国际象棋棋盘的图案。
思路
循环控制 分隔错开即可。&1和%2==0效果一样,&1是看二进制的最低位是否为1,如果是1则为奇数,0为偶数。
代码实现
C语言
/*
题目:输出类似于国际象棋棋盘的图案。
*/
#include <stdio.h>
int main() {
int i = 0;
int j = 0;
for(i = 0; i < 8; i++) {
for(j = 0; j < 8; j++)
if((i + j)&1) {
printf(" ");
} else {
printf("■");
}
printf("\n");
}
return 0;
}
008:打印九九乘法表
题目
输出9*9乘法表。
思路
这是一道经典的题目,输出九九乘法表,使用两层循环控制即可。
代码实现
C语言
/*
输出9*9乘法表。
*/
#include <stdio.h>
int main(){
int i,j;
for(i=1;i<=9;i++){
for(j=1;j<=i;j++){
printf("%d*%d=%d\t",j,i,i*j);
}
printf("\n");
}
return 0;
}
009:输出国际象棋棋盘
题目
输出国际象棋棋盘。(8行*8列)
思路
和第七题一样,不过这里我们使用while循环重新实现一遍。
代码实现
C语言
/*
题目:输出国际象棋棋盘。(8行*8列)
*/
#include <stdio.h>
int main() {
int i = 8;
while(i--) {
int j = 8;
while(j--) {
if((i + j)&1) {
printf(" ");
} else {
printf("■");
}
}
printf("\n");
}
return 0;
}
010:打印楼梯
题目
打印楼梯,同时在楼梯上方打印两个笑脸。
思路
因为编码问题打印不了笑脸,用两个①代替
代码实现
C语言
/*
题目:打印楼梯,同时在楼梯上方打印两个笑脸。
*/
#include <stdio.h>
int main() {
int i,j;
printf("①①\n");
for(i=1; i<11; i++) {
for(j=1; j<=i; j++) {
printf("■■");
}
printf("\n");
}
return 0;
}
011:兔子生兔子
题目
古典问题(兔子生崽):有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?(输出前40个月即可)
思路
我们可以理解成第三个月以后的值,是前两个月相加,这样就清晰很多了。这道题也是动态规划的入门题目,dp[i]=dp[i-1]+dp[i-2]。
代码实现
C语言
/*
题目:古典问题(兔子生崽):
有一对兔子,从出生后第3个月起每个月都生一对兔子,
小兔子长到第三个月后每个月又生一对兔子,
假如兔子都不死,问每个月的兔子总数为多少?(输出前40个月即可)
*/
#include <stdio.h>
void run() {
int f1=1,f2=1,i;
for(i=1; i<=40; i++) {
if(i>=3) {
//下个月是上两个月之和(从第三个月开始)
int k=f1+f2;
f1=f2;
f2=k;
}
printf("第%d月有%d个\n",i,f2);
}
}
void run1(){
int dp[40]={1,1},i;
for(i=0;i<40;i++){
if(i>=2){
dp[i]=dp[i-1]+dp[i-2];
}
printf("第%d月有%d个\n",i+1,dp[i]);
}
}
int main() {
// 传统做法
run();
// 动态规划做法
// run1();
return 0;
}
012:判断两数之间的素数
题目
判断101到200之间的素数。
思路
想要代码优雅,就多使用函数,用一个函数来判断是否是素数。我们知道,质数的定义就是他的约数只有1和它本身,所以我们用从2开始到n-1的数依次对n取余,如果可以整除的话说明它不是质数。
有朴素做法,埃氏筛法,欧拉筛法等做法。这里就不对算法做过多介绍了,详情请看我之前发的文章:素数求和(筛法合集)
代码实现
C语言
/*
判断101到200之间的素数。
*/
#include <stdio.h>
int vis(int n){
if(n<2)return 0;
int i;
for(i=2;i<n;i++){
if(n%i==0){
return 0;
}
}
return 1;
}
int main() {
int i,z=0;
for (i=101; i<=200; i++) {
if(vis(i)){
z++;
printf("%d ",i);
}
}
printf("\n共%d个",z);
return 0;
}
013:水仙花数
题目
打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身。例如:153是一个"水仙花数",因为153 = 1的三次方+5的三次方+3的三次方。
思路
又是一道经典的算法,取出每一位上的数,变成立方相加后和原值比较即可。不过使用循环取最低位明显是更优雅的做法。(%10可以取出最低位上的数)
代码实现
C语言
/*
打印出所有的"水仙花数"
所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身。
例如:153是一个"水仙花数"
因为153 = 1的三次方+5的三次方+3的三次方。
*/
#include <stdio.h>
int vis(int n){
int x,y,z;
// 取出三位
x=n%10;
y=n/10%10;
z=n/100%10;
return n==x*x*x+y*y*y+z*z*z;
}
// 循环做法
int vis1(int n){
int z=0,k=n;
while(n){
// 取出最低位
int t=n%10;
z+=t*t*t;
// 去除最低位
n/=10;
}
return k==z;
}
int main() {
int i,x,y,z;
for(i=100; i<1000; i++) {
if(vis1(i)){
printf("%d\n",i);
}
}
return 0;
}
014:分解质因数
题目
将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5。
思路
对n进行分解质因数,应先找到一个最小的质数k,然后按下述步骤完成:
(1)n能被k整除,则应打印出k的值,并用n除以k的商,作为新的正整数n。重复执行。
(2)如果n不能被k整除,则用k+1作为k的值,重复执行第一步。
代码实现
C语言
/*
将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5。
*/
#include <stdio.h>
int main() {
int n,i;
scanf("%d",&n);
printf("%d=",n);
for(i=2; i<=n; i++) {
while(n%i==0) {
printf("%d",i);
n/=i;
// 如果不是最后一位 输出乘号
if(n!=1) printf("*");
}
}
return 0;
}
015:条件运算符的嵌套
题目
利用条件运算符的嵌套:学习成绩>=90分的同学用A表示,60-89分之间的用B表示,60分以下的用C表示。
思路
这道题有一个小细节,就是不加括号也可以哦。
(条件运算符=>
(条件)?(条件满足执行这里):(条件不满足执行这里) )
代码实现
C语言
/*
利用条件运算符的嵌套:
学习成绩>=90分的同学用A表示
60-89分之间的用B表示
60分以下的用C表示
*/
#include <stdio.h>
int main() {
int score;
char grade;
scanf("%d",&score);
grade = (score>=90) ? 'A' : ( (score>=60) ? 'B' : 'C' );
// grade = score>=90 ? 'A' : score>=60 ? 'B' : 'C';
printf("%c\n",grade);
return 0;
}
016:最大公约数与最小公倍数
题目
输入两个正整数m和n,求其最大公约数和最小公倍数。
思路
简单算法就是从n到1,找能被两个数整除的数,找到就是最大公约数,再从n到n*m找能整除两数的数,找到就是最小公倍数。
还有就是欧几里得算法求解最大公约数(gcd),最小公倍数(lcm)和gcd有关系,gcd*lcm=n*m;知道最大公约数就能算最小公倍数了。这里不多介绍算法,详见代码。
代码实现
C语言
/*
输入两个正整数m和n,求其最大公约数和最小公倍数。
*/
#include <stdio.h>
//普通算法求解
void run(int n,int m) {
int i;
for(i=n; i>=1; i--) {
if(n%i==0&&m%i==0) {
printf("gcd=%d\n",i);
break;
}
}
for(i=n; i<=n*m; i++) {
if(i%n==0&&i%m==0) {
printf("lcm=%d\n",i);
break;
}
}
}
//辗转相除法求解
void run1(int n,int m) {
int t,r,a=n,b=m;
//为了确保是大数除小数
if (m<n) {
t=m;
m=n;
n=t;
}
//辗转相除
while((m%n)!=0) {
r=m%n;
m=n;
n=r;
};
int gcd = n;
int lcm = a*b/gcd;
printf("gcd=%d\nlcm=%d",gcd,lcm);
}
// 位运算求解
void run2(int x, int y) {
int a=x,b=y;
/*
gcd(a,b) = gcd(b,a mod b)
#首先声明^就是异或,a^a=0,a^0=a其次连等是从右往左结合
x1=x%y;
y1=y^x1=y^(x%y)
x2=x1^y1=(x%y)^y^(x%y)=y
y2=y1^x2=y^(x%y)^y=x%y
即:
x'=y, y'=x%y
gcd(x,y) = gcd(y,x%y) = gcd(x',y')
*/
while(y^=x^=y^=x%=y);
int gcd = x;
int lcm = a*b/gcd;
printf("gcd=%d\nlcm=%d",gcd,lcm);
}
int main() {
int n,m;
scanf("%d %d",&n,&m);
run(n,m);
return 0;
}
017:字符统计
题目
输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。
思路
直接if判断即可,输入一个字符就判断一个字符,到回车('\n')停止。注意字符是用单引号。
代码实现
C语言
/*
输入一行字符
分别统计出其中英文字母、空格、数字和其它字符的个数。
*/
#include <stdio.h>
int main() {
char c;
int letters=0,spaces=0,digits=0,others=0;
while((c=getchar())!='\n') {
if((c>='a'&&c<='z')||(c>='A'&&c<='Z'))
letters++;
else if(c>='0'&&c<='9')
digits++;
else if(c==' ')
spaces++;
else
others++;
}
printf("字母=%d,数字=%d,空格=%d,其他=%d\n",letters,digits,spaces,others);
return 0;
}
018:数字序列求和
题目
求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加由键盘控制。
思路
这也是一道经典题目,详见代码。
代码实现
C语言
/*
求s=a+aa+aaa+aaaa+aa...a的值
其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加)
几个数相加由键盘控制。
*/
#include <stdio.h>
int main() {
int z=0,a=2,n,t;
scanf("%d",&n);
while(n) {
t+=a;// 这里的t在循环中变成了2 22 222
z+=t;
a=a*10;
n--;
}
printf("a+aa+...=%d\n",z);
return 0;
}
019:寻找完数
题目
一个数如果恰好等于它的真因子之和,这个数就称为"完数"。例如6=1+2+3。编程找出1000以内的所有完数。
思路
寻找因子相加即可,这里将因子放到了数组里面,方便打印公式。
代码实现
C语言
/*
一个数如果恰好等于它的真因子之和,这个数就称为"完数"。
例如6=1+2+3。编程找出1000以内的所有完数。
*/
#include <stdio.h>
int main() {
int i,j,n;
int a[256];
for(i=2; i<=1000; i++) {
int sum=0,k=0;
for(j=1; j<i; j++) {
if(i%j==0) {
sum+=j;
a[k++]=j;
}
}
if(i==sum) {
printf("%d=%d",i,a[0]);
for(n=1; n<k; n++)
printf("+%d",a[n]);
printf("\n");
}
}
return 0;
}
020:自由落体的小球
题目
一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第10次反弹多高?
思路
又是一道经典算法,第一次经过的是从高到低一次,后面都是从低到高再从高到低两次。
代码实现
C语言
/*
一球从100米高度自由落下,每次落地后反跳回原高度的一半;
再落下,求它在第10次落地时,共经过多少米?第10次反弹多高?
*/
#include <stdio.h>
int main() {
float h=100,s=0;
int i;
for(i=1; i<=10; i++) {
if(i==1) {
s=s+h;
} else {
s=s+2*h;
}
h=h/2;
printf("第%d次落地时,共经过%f米,第%d次反弹高%f米\n",i,s,i,h);
}
return 0;
}
021:猴子吃桃
题目
猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,又多吃了一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,只剩下一个桃子了。求第一天共摘了多少。
思路
经典题目+1,这个向前反推即可。
代码实现
C语言
/*
猴子吃桃问题:
猴子第一天摘下若干个桃子,当即吃了一半,又多吃了一个。
第二天早上又将剩下的桃子吃掉一半,又多吃了一个。
以后每天早上都吃了前一天剩下的一半零一个。
到第10天早上想再吃时,只剩下一个桃子了。
求第一天共摘了多少。
*/
#include <stdio.h>
int main() {
int day = 10, x1 = 0, x2 = 1;
while(day) {
printf("第%d天还有%d个\n",day,x2);
x1=(x2+1)*2; // 第一天的桃子数是第2天桃子数加1后的2倍
x2=x1;
day--;
}
return 0;
}
022:比赛名单
题目
两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单。
思路
这是一道无语的题目。
代码实现
C语言
/*
两个乒乓球队进行比赛,各出三人。
甲队为a,b,c三人,乙队为x,y,z三人。
已抽签决定比赛名单。有人向队员打听比赛的名单。
a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单。
*/
#include <stdio.h>
int main() {
char i,j,k;
for(i='x'; i<='z'; i++) {
for(j='x'; j<='z'; j++) {
if(i!=j) {
for(k='x'; k<='z'; k++) {
if(i!=k&&j!=k) {
if(i!='x'&&k!='x'&&k!='z') {
printf("顺序为:a--%c\tb--%c\tc--%c\n",i,j,k);
}
}
}
}
}
}
}
023:打印菱形
题目
打印出如下图案(菱形)。
*
***
*****
*******
*****
***
*
思路
又是一道经典,看我代码,有简单解法哦。
代码实现
C语言
/*
打印出如下图案(菱形)。
*/
#include <stdio.h>
#include <stdlib.h>
void run(int n) {
int i,j;
for( i=-n/2; i<=n/2; i++) {
for(j=1; j<=abs(i); j++)
printf(" ");
for(j=1; j<=n-abs(i*2); j++)
printf("*");
printf("\n");
}
}
void run1(int n) {
int i,j,k;
for(i=1; i<=n/2+1; i++) {
for(j=1; j<=n/2+1-i; j++)
printf(" ");
for(k=1; k<=2*i-1; k++)
printf("*");
printf("\n");
}
for(i=1; i<=n/2; i++) {
for(j=1; j<=i; j++)
printf(" ");
for(k=1; k<=n-2*i; k++)
printf("*");
printf("\n");
}
}
int main() {
run(7);
// run1(7);
}
024:分数序列求和
题目
有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和。
思路
这道真的是经典,很多学校很爱出这道题。
代码实现
C语言
/*
有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...
求出这个数列的前20项之和。
*/
#include <stdio.h>
int main() {
int i,t;
float sum=0;
float a=2,b=1;
for(i=1; i<=20; i++) {
sum=sum+a/b;
t=a;
a=a+b;
b=t;
}
printf("%9.6f\n",sum);
}
025:阶乘求和
题目
求1+2!+3!+...+20!的和。
思路
经典题目又又又又+1
代码实现
C语言
/*
求1+2!+3!+...+20!的和。
*/
#include <stdio.h>
int main() {
int i;
double sum=0,mix=1;
for(i=1; i<=20; i++) {
mix=mix*i;//mix为1! 2! 3!...
sum=sum+mix;
}
printf("%lf\n",sum);
}
026:递归求阶乘
题目
利用递归方法求5!
思路
递归比较消耗栈的空间,求到20!或者再多点就会爆内存,一般还是不用递归求阶乘比较好。
代码实现
C语言
/*
利用递归方法求5!
*/
#include <stdio.h>
int fact(int n) {
if(n==0) {
return 1;
}
return n*fact(n-1);
}
int main() {
int i;
int fact(int);
for(i=0; i<6; i++) {
printf("%d!=%d\n",i,fact(i));
}
}
027:递归字符反转
题目
利用递归函数调用方式,将所输入的5个字符,以相反顺序打印出来。
思路
用这道题理解递归更好哦。
代码实现
C语言
/*
利用递归函数调用方式,将所输入的5个字符,以相反顺序打印出来。
*/
#include <stdio.h>
void rvs(char *s){
if(*s=='\0'){
return;
}
rvs(s+1);
printf("%c",*s);
}
int main() {
char s[10];
scanf("%s",s);
rvs(s);
}
028:计算岁数
题目
有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁。问第4个人岁数,他说比第3个人大2岁。问第三个人,又说比第2人大两岁。问第2个人,说比第一个人大两岁。最后问第一个人,他说是10岁。请问第五个人多大?
思路
这道题也可以用递归做,你想到了嘛。
要想知道第五个人岁数,需知道第四人的岁数,依次类推,推到第一人(10岁),再往回推。
代码实现
C语言
/*
有5个人坐在一起,问第五个人多少岁?
他说比第4个人大2岁。
问第4个人岁数,他说比第3个人大2岁。
问第三个人,又说比第2人大两岁。
问第2个人,说比第一个人大两岁。
最后问第一个人,他说是10岁。请问第五个人多大?
*/
#include <stdio.h>
int age1(int n) {
if(n==1){
return 10;
}
return age1(n-1)+2;
}
int age2(){
int i,z=10;
for(i=1;i<5;i++){
printf("第%d个人%d岁\n",i,z);
z+=2;
}
return z;
}
int main() {
printf("第%d个人%d岁\n",5,age1(5));
}
029:数字逆序
题目
给一个不多于5位的正整数,要求:一、求它是几位数,二、逆序打印出各位数字。
思路
用%10依次获得最低位即可。
代码实现
C语言
/*
给一个不多于5位的正整数
要求:一、求它是几位数,二、逆序打印出各位数字。
*/
#include <stdio.h>
void run1(int n){
int k=0;
while(n){
printf("%d",n%10);
n/=10;
k++;
}
printf("这是%d位数",k);
}
void run2(int n){
int k=0,a=n;
while(n){
n/=10;
k++;
}
printf("这是%d位数,逆序为",k);
while(a){
printf("%d",a%10);
a/=10;
}
}
int main( ) {
int n;
scanf("%d",&n);
run2(n);
}
030:判断回文数
题目
一个5位数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同。
思路
回文数倒看和它也相等。当然如果当成字符串看更简单哦。
代码实现
C语言
/*
一个5位数,判断它是不是回文数。
即12321是回文数,个位与万位相同,十位与千位相同。
*/
#include <stdio.h>
#include <string.h>
// 判断数字是否回文
// 12321倒看也等于12321
int vis1(int n) {
int a=n,s=0;
while(a) {
s=s*10+a%10;
a=a/10;
}
return n==s;
}
// 当成字符串检测
int vis2(char *s) {
int i=0,j=strlen(s)-1;
while(i<j) {
if(s[i]!=s[j]) {
return 0;
}
i++;
j--;
}
return 1;
}
int main() {
int n;
scanf("%d",&n);
printf(vis1(n)?"%d是回文数":"%d不是回文数",n);
// char s[10];
// scanf("%s",s);
// printf(vis2(s)?"%s是回文数":"%s不是回文数",s);
}
031:判断星期几
题目
请输入星期几的第一个字母来判断一下是星期几,如果第一个字母一样,则继续判断第二个字母。
思路
这道题挨个判断很麻烦,不如直接判断。注意getchar吸收回车
代码实现
C语言
/*
请输入星期几的第一个字母来判断一下是星期几
如果第一个字母一样,则继续判断第二个字母。
*/
#include <stdio.h>
int main() {
char i,j;
printf("请输入第一个字母:\n");
scanf("%c",&i);
// scanf("%c",&j);的问题,第二次是读入的一个换行符,而不是输入的字符
// 因此需要加一个getchar() 吃掉换行符
getchar();
switch(i) {
case 'm':
printf("monday\n");
break;
case 'w':
printf("wednesday\n");
break;
case 'f':
printf("friday\n");
break;
case 't':
printf("请输入下一个字母\n");
scanf("%c",&j);
if (j=='u') {
printf("tuesday\n");
break;
}
if (j=='h') {
printf("thursday\n");
break;
}
case 's':
printf("请输入下一个字母\n");
scanf("%c",&j);
if (j=='a') {
printf("saturday\n");
break;
}
if (j=='u') {
printf("sunday\n");
break;
}
default :
printf("error\n");
break;
}
return 0;
}
032:删除指定字符
题目
删除一个字符串中的指定字母,如:字符串 "aca",删除其中的 a 字母。
思路
用指向下标的变量修改数组内容。
代码实现
C语言
/*
删除一个字符串中的指定字母
如:字符串 "aca",删除其中的 a 字母。
*/
#include <stdio.h>
// 删除字符串中指定字母函数
char* deleteCharacters(char * str, char charSet) {
int i,j=0;
for(i = 0; str[i]!='\0'; i++) {
if(str[i]!=charSet) {
str[j++]=str[i];
}
}
str[j] = '\0';
return str;
}
int main() {
char c = 'a'; // 要删除的字母
char s[10] = "aca"; // 目标字符串
deleteCharacters(s, c);
printf("%s\n", s);
return 0;
}
033:判断素数
题目
判断一个数字是否为质数(素数)。
思路
和第12题一样。
代码实现
C语言
/*
判断一个数字是否为质数(素数)。
*/
#include <stdio.h>
int vis(int n) {
if(n<2)return 0;
int i;
for(i=2; i<n; i++) {
if(n%i==0) {
return 0;
}
}
return 1;
}
int main() {
int n;
scanf("%d",&n);
printf(vis(n)?"%d是素数":"%d不是素数",n);
return 0;
}
034:函数调用
题目
练习函数调用。在函数内调用函数。
思路
在函数内调用函数就好啦。
代码实现
C语言
/*
练习函数调用。在函数内调用函数。
*/
#include <stdio.h>
void hello_world(void) {
printf("Hello, world!\n");
}
void three_hellos(void) {
int counter;
for (counter = 1; counter <= 3; counter++)
hello_world();/*调用此函数*/
}
int main() {
three_hellos();/*调用此函数*/
return 0;
}
035:字符串反转
题目
字符串反转,如将字符串 "abcde" 反转为 "edcba"。
思路
双指针,一个指向头一个指向最后,依次进行交换。
代码实现
C语言
/*
字符串反转,如将字符串 "abcde" 反转为 "edcba"。
*/
#include <stdio.h>
#include <string.h>
char* rvs(char *s){
int i=0,j=strlen(s)-1;
while(i<j){
char c=s[i];
s[i]=s[j];
s[j]=c;
i++;
j--;
}
return s;
}
int main() {
char s[10] = "abcde";
rvs(s);
printf("%s",s);
}
036:100以内的素数
题目
求100之内的素数。
思路
这是第三次出现素数了,素数的知识点很重要。
代码实现
C语言
/*
求100之内的素数。
*/
#include <stdio.h>
int vis(int n) {
if(n<2)return 0;
int i;
for(i=2; i<n; i++) {
if(n%i==0) {
return 0;
}
}
return 1;
}
int main() {
int i,z=0;
for (i=0; i<=100; i++) {
if(vis(i)) {
z++;
printf("%d ",i);
}
}
printf("\n共%d个",z);
return 0;
}
037:对十个数排序
题目
对10个数进行排序。
思路
和第5题很像,第5题介绍了系统排序,这里我们用最经典的三大排序 冒泡排序 选择排序和插入排序实现一遍。
了解十大排序请看菜鸟教程:十大经典排序算法
代码实现
C语言
/*
对10个数进行排序
*/
#include <stdio.h>
/*
冒泡排序
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。
这步做完后,最后的元素会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
*/
void bubble_sort(int arr[], int len) {
int i, j, temp;
for (i = 0; i < len - 1; i++) {
for (j = 0; j < len - 1 - i; j++) {
// 将大的数放到后面
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
/*
选择排序
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
重复第二步,直到所有元素均排序完毕。
*/
void selection_sort(int arr[], int len) {
int i,j,temp;
for (i = 0 ; i < len - 1 ; i++) {
int min = i;
//走访未排序的元素
for (j = i + 1; j < len; j++) {
//找到目前最小值
if (arr[j] < arr[min]) {
min = j;
}
}
temp = arr[min];
arr[min] = arr[i];
arr[i] = temp;
}
}
/*
插入排序
将第一待排序序列第一个元素看做一个有序序列
把第二个元素到最后一个元素当成是未排序序列。
从头到尾依次扫描未排序序列
将扫描到的每个元素插入有序序列的适当位置。
如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。
*/
void insertion_sort(int arr[], int len) {
int i, j, key;
for (i = 1; i < len; i++) {
key = arr[i];
for (j = i - 1; j >= 0 && arr[j] > key; j--) {
arr[j + 1] = arr[j];
}
arr[j + 1] = key;
}
}
int main() {
int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 };
int len = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, len);
// selection_sort(arr, len);
// insertion_sort(arr, len);
int i;
for (i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
return 0;
}
038:对角线元素之和
题目
求一个3*3矩阵对角线上的元素之和。
思路
经典题目+1,找出对角线上的规律即可。
对于对角线上有 i=j;
对于副对角线有 i+j=4;
这道题没有明说,我看其它解法都是按照主对角线做的。
进阶题目&详解请看:1115: DNA(二维数组思想)
代码实现
C语言
/*
求一个3*3矩阵对角线元素之和
*/
#include <stdio.h>
#define N 3
int main() {
int i,j,a[N][N],sum=0;
printf("请输入矩阵(3*3):\n");
for(i=0; i<N; i++){
for(j=0; j<N; j++){
scanf("%d",&a[i][j]);
}
}
for(i=0; i<N; i++){
sum+=a[i][i];
}
printf("对角线之和为:%d\n",sum);
return 0;
}
039:插入数组
题目
有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中。
思路
分成两步 一个是找到它的位置 另一个是将后面的数后移让出位置。
代码实现
C语言
/*
有一个已经排好序的数组。
现输入一个数,要求按原来的规律将它插入数组中。
*/
#include <stdio.h>
int main() {
int a[11]= {1,4,6,9,13,16,19,28,40,100};
int i,j,num=10;
printf("原始数组是:\n");
for(i=0; i<10; i++) {
printf("%4d",a[i]);
}
printf("\n插入一个新的数字: %d\n",num);
// 找到位置
for(i=0; i<10; i++) {
if(num<a[i])break;
}
// 后移位置
for(j=10; j>=i; j--) {
a[j]=a[j-1];
}
// 插入
a[i]=num;
printf("插入后的数组是:\n");
for(i=0; i<11; i++) {
printf("%4d",a[i]);
}
return 0;
}
040:数组逆序
题目
将一个数组逆序后输出。
思路
和第35题是不是很像?照做即可!
代码实现
C语言
/*
将一个数组逆序后输出。
*/
#include <stdio.h>
#define N 10
int main() {
int a[N]= {0,1,2,3,4,5,6,7,8,9};
int i,j,t;
printf("原始数组是:\n");
for(i=0; i<N; i++)
printf("%d ",a[i]);
for(i=0,j=N-1; i<j; i++,j--) {
t=a[i];
a[i]=a[j];
a[j]=t;
}
printf("\n逆序后的数组:\n");
for(i=0; i<N; i++)
printf("%d ",a[i]);
printf("\n");
return 0;
}
041:static静态变量
题目
学习static定义静态变量的用法。
思路
当一个局部变量被声明为static
时,它的生命周期会延长到整个程序执行期间,而不是仅仅在定义它的代码块内。这意味着,即使该函数已经返回,该变量的值仍然保持不变。
代码实现
C语言
/*
学习static定义静态变量的用法。
*/
#include <stdio.h>
void f() {
int i = 0;
static int si = 0;
i++;
si++;
printf("i=%d\n", i);
printf("static si = %d\n", si);
}
int main() {
int i;
for (i = 0; i < 4; i++) {
f();
}
return 0;
}
042:auto用法
题目
学习使用auto定义变量的用法。
思路
auto
关键字用于声明一个变量的存储类型为自动存储类型。即数据类型由编译器自己确定。
这道题后部分要和43题一块看。
代码实现
C语言
/*
学习使用auto定义变量的用法。
*/
#include <stdio.h>
int main() {
int cnt = 5,i;
for (i = 0; i < 4; i++) {
printf("cnt 变量为 %d\n", cnt);
cnt++;
{
// auto关键字用于声明一个变量的存储类型为自动存储类型
// 可以简化变量声明,让编译器自己确定变量的存储类型
auto cnt = 1;
// 优先使用生存域小的变量
// 下一次循环该变量被重新定义
printf("内置模块 cnt 变量为 %d\n", cnt);
cnt++;
}
}
return 0;
}
043:static另一种用法
题目
学习使用static的另一用法。
思路
static的变量只初始化一次 并且一直存活(但只能在自己的作用域里使用)
代码实现
C语言
/*
学习使用static的另一用法。
*/
#include <stdio.h>
int main() {
int cnt = 5,i;
for (i = 0; i < 4; i++) {
printf("cnt 变量为 %d\n", cnt);
cnt++;
{
static int cnt = 1;
printf("内置模块 cnt 变量为 %d\n", cnt);
cnt++;
}
}
return 0;
}
044:全局变量用法
题目
学习使用external的用法。
思路
全局变量全局可用。
代码实现
C语言
/*
学习使用external的用法。(全局变量)
*/
#include <stdio.h>
int a=2, b=2, c;
void add() {
int a;
a = 1;// 这里使用的是函数内部的a
c = a + b;// 这里是1 + 2
}
int main() {
add();
printf("c = %d\n", c);
return 0;
}
045:register用法
题目
学习使用register定义变量的方法。
思路
在早期版本中,可以使用register
关键字来建议编译器将变量存储在寄存器中,以提高性能。然而,由于现代编译器已经能够自动优化性能,因此使用register
已经不再推荐。
代码实现
C语言
/*
学习使用register定义变量的方法。
*/
#include <stdio.h>
int main() {
register int i;//将变量i存储在寄存器中
int sum = 0;
for (i = 0; i <= 10; i++) {
sum += i;
}
printf("%d\n", sum);
return 0;
}
046:宏命令练习一
题目
宏#define命令练习
思路
在C语言中,宏定义是一种预处理指令,用于创建宏。宏是一种文本替换机制,它允许程序员使用一个符号(宏名)来表示一个字符串(宏的替换文本)。在预处理阶段,编译器会用宏的替换文本替换程序中的宏名。
代码实现
C语言
/*
宏#define命令练习
*/
#include <stdio.h>
#define TRUE 1
#define FALSE 0
#define SQ(x) (x)*(x)
int main() {
int num;
int flag = 1;
//num < 20 程序将终止
while (flag) {
scanf("%d", &num);
printf("该数的平方为 %d \n", SQ(num));
if (num >= 20)
flag = TRUE;
else
flag = FALSE;
}
return 0;
}
047:宏命令练习二
题目
对宏命令实现函数功能
代码实现
C语言
/*
对宏命令实现函数功能
*/
#include <stdio.h>
#define exchange(a,b) { int t;t=a;a=b;b=t;}//注意放在一行里
int main() {
int x = 5;
int y = 10;
printf("x=%d; y=%d\n", x, y);
exchange(x, y);
printf("x=%d; y=%d\n", x, y);
return 0;
}
048:宏命令练习三
题目
理解宏命令和函数的区别
思路
宏命令 只是在编译之前实现预编译替换!!
注意,在宏定义中,参数必须用括号括起来,以避免因为运算符优先级引起的错误。例如,如果没有在参数周围使用括号,以下宏定义可能会导致错误。
代码实现
C语言
/*
理解宏命令和函数的区别
*/
#include <stdio.h>
#define f(a,b) a*b
//正确做法
//#define f(a,b) (a)*(b)
int f1(int a,int b){
return a*b;
}
int main() {
printf("%d\n", f(5+5,5+5));//得35 这里实际为5+5*5+5 宏定义只会实现替换
printf("%d\n", f1(5+5,5+5));//得100 自动加好
return 0;
}
049:#if #ifdef #ifndef综合应用
题目
if #ifdef和#ifndef的综合应用
思路
这段C语言代码演示了预处理器宏(macros)的使用,特别是条件编译。让我们逐步分析这段代码:
- 定义了两个宏函数:
MAXIMUM
和MINIMUM
。这两个函数用于返回两个参数中的最大值和最小值。
#define MAXIMUM(x,y) (x>y)?x:y | |
#define MINIMUM(x,y) (x>y)?y:x |
- 在
main
函数中,定义了两个整数变量a
和b
,并分别赋值为10和20。 - 接下来的部分使用了条件编译。
#ifdef MAX
检查是否定义了MAX
宏。如果定义了,它会打印出a和b中的最大值。否则,它会打印出a和b中的最小值。
#ifdef MAX | |
printf("w 大 %d\n", MAXIMUM(a, b)); | |
#else | |
printf("w 小 %d\n", MINIMUM(a, b)); | |
#endif |
- 接下来的部分与上面的部分类似,但是它检查是否定义了
MIN
宏:
#ifndef MIN | |
printf("x 小 %d\n", MINIMUM(a, b)); | |
#else | |
printf("x 大 %d\n", MAXIMUM(a, b)); | |
#endif |
- 接下来,
MAX
宏被取消定义:
#undef MAX |
- 再次检查
MAX
宏是否被定义,这次它应该没有被定义,所以会打印出a和b中的最小值。 - 最后,定义了
MIN
宏,并再次检查它是否被定义。这次,它会打印出a和b中的最大值。 main
函数返回0,程序结束。
当你运行这段代码时,输出将是:
w 小 10 | |
x 大 20 | |
y 小 10 | |
z 大 20 |
这是条件编译
代码实现
C语言
/*
#if #ifdef和#ifndef的综合应用
*/
#include <stdio.h>
#define MAX
#define MAXIMUM(x,y) (x>y)?x:y
#define MINIMUM(x,y) (x>y)?y:x
int main() {
int a = 10, b = 20;
#ifdef MAX
printf("w 大 %d\n", MAXIMUM(a, b));
#else
printf("w 小 %d\n", MINIMUM(a, b));
#endif
#ifndef MIN
printf("x 小 %d\n", MINIMUM(a, b));
#else
printf("x 大 %d\n", MAXIMUM(a, b));
#endif
#undef MAX
#ifdef MAX
printf("y 大 %d\n", MAXIMUM(a, b));
#else
printf("y 小 %d\n", MINIMUM(a, b));
#endif
#define MIN
#ifndef MIN
printf("z 小 %d\n", MINIMUM(a, b));
#else
printf("z 大 %d\n", MAXIMUM(a, b));
#endif
return 0;
}
050:.h文件和.c文件引用
题目
使用#include导入.h和.c文件
思路
注意<>和""的区别 <>在系统的文件中寻找,""在用户的文件中寻找 没找到再去找系统的文件。
代码实现
C语言
50.h
int mmax(int a,int b){
return a>b?a:b;
}
50.c
/*
使用#include导入.h和.c文件
*/
#include <stdio.h>
#include "50.h"
int main() {
int a=10,b=5;
printf("大的数是%d",mmax(a,b));
return 0;
}
051:按位与
题目
学习按位与&
思路
全1得1
代码实现
C语言
/*
学习使用按位与 &
0&0=0; 0&1=0; 1&0=0; 1&1=1 。
全1得1
*/
#include <stdio.h>
int main() {
int a,b;
a=7; // 7的二进制为0111
b=a&3; // 3的二进制为0011 &得到0011(3)
printf("a & b(decimal) 为 %d \n",b);
b&=0; // 0000&0011 = 0000
printf("a & b(decimal) 为 %d \n",b);
return 0;
}
052:按位或
题目
学习按位或|
思路
有1得1
代码实现
C语言
/*
学习使用按位或 |
0|0=0; 0|1=1; 1|0=1; 1|1=1 。
有1得1
*/
#include <stdio.h>
int main() {
int a,b;
a=7;
b=a|3; //0111|0011 = 0111
printf("b 的值为 %d \n",b);
b|=0; //0111|0000 = 0111
printf("b 的值为 %d \n",b);
return 0;
}
053:按位异或
题目
学习按位异或
思路
相异得1
性质:a^0=a a^a=0
代码实现
C语言
/*
学习使用按位异或 ^
0^0=0; 0^1=1; 1^0=1; 1^1=0
相异得1
性质:a^0=a a^a=0
*/
#include <stdio.h>
int main() {
int a,b;
a=7;
b=a^3; //0111^0011 = 0100(4)
printf("b 的值为 %d \n",b);
b^=0; //0100^0000 = 0100(4)
printf("b 的值为 %d \n",b);
return 0;
}
054:取二进制中的某几位
题目
取一个整数 a 从右端开始的 4~7 位
思路
(1)先使 a 右移 4 位。
(2)设置一个低 4 位全为 1,其余全为 0 的数,可用~(~0<<4)
(3)将上面二者进行 & 运算。
做法二 创建一个4-7位为1 其余位为0的数 与a做与运算 然后整体右移四位
代码实现
C语言
/*
取一个整数 a 从右端开始的 4~7 位
程序分析:
(1)先使 a 右移 4 位。
(2)设置一个低 4 位全为 1,其余全为 0 的数,可用~(~0<<4)
(3)将上面二者进行 & 运算。
*/
#include <stdio.h>
void run(){
// 做法二 创建一个4-7位为1 其余位为0的数 与a做与运算 然后整体右移四位
int a=0b1110010011,b=0,d,i;
for(i=4;i<=7;i++){
b+=1<<i;
}
//此时b为 0000 1111 0000(240)
//a&b = 0011 1001 0011 & 0000 1111 0000 =0000 1001 0000
//>>4 = 0000 1001(9)
d=(a&b)>>4;
printf("a=%d\nd=%d\n",a,d);
}
int main() {
//0b开头转为二进制储存 0x十六进制 0八进制 不加默认十进制
int a=0b1110010011,b,c,d;//0011 1001 0011(915)
b=a>>4; //b=0011 1001(a整体右移四位 低位舍去)
// 优先级为~((~0)<<4)
// ~0=1111 1111(全1) ~0<<4为1111 0000(低四位为0)
c=~(~0<<4); //c=0000 1111(取反后 低四位为1 其余位为0)
d=b&c; //0011 1001 & 0000 1111 = 0000 1001(9)
printf("a=%d\nd=%d\n",a,d);
// run();
return 0;
}
055:按位取反
题目
学习使用按位取反~
思路
数字在计算机里面都是用二进制补码储存
代码实现
C语言
/*
学习使用按位取反~
~0=1; ~1=0;
数字在计算机里面都是用二进制补码储存
*/
#include <stdio.h>
int main() {
int a,b;
a=0b0011;
b=~a; // b=1100(此时为补码形式)转为源码
//(补码最高位为符号位 剩余位取反后+1) 1,100(-4)
printf("a 的按位取反值为(十进制) %d \n",b);
a=~a;// -4 源码为-0000 0100 转为补码(源码取反后+1)1111 1100 (fc)
printf("a 的按位取反值为(十六进制) %x \n",a);
return 0;
}
056:画圆形
题目
画图,学用circle画圆形。
思路
先在https://www.easyx.cn/ 下载安装EasyX库
代码实现
C语言
#include <easyx.h> // 引用图形库头文件
#include <conio.h>
int main()
{
initgraph(640, 480); // 创建绘图窗口,大小为 640x480 像素
circle(200, 200, 100); // 画圆,圆心(200, 200),半径 100
_getch(); // 按任意键继续
closegraph(); // 关闭绘图窗口
}
057:画直线
题目
画图,学用line画直线。
代码实现
C语言
#include <graphics.h>
#include <conio.h>
void main()
{
initgraph(640, 480);
// 画一条直线
line(0, 0, 300, 300);
// 按任意键继续
getch();
closegraph();
}
058:画矩形
题目
学用rectangle画矩形。
代码实现
C语言
#include <graphics.h>
#include <conio.h>
void main()
{
initgraph(640, 480);
// 绘制矩形框
rectangle(50, 50, 550, 400);
// 按任意键继续
getch();
closegraph();
}
059:画图综合一
题目
画图,综合例子。
代码实现
C语言
#include <graphics.h>
#include <time.h>
#include <conio.h>
int main()
{
// 设置随机函数种子
srand((unsigned)time(NULL));
// 初始化图形模式
initgraph(640, 480);
int x, y;
char c;
settextstyle(16, 8, _T("Courier")); // 设置字体
// 设置颜色
settextcolor(GREEN);
setlinecolor(BLACK);
for (int i = 0; i <= 479; i++)
{
// 在随机位置显示三个随机字母
for (int j = 0; j < 3; j++)
{
x = (rand() % 80) * 8;
y = (rand() % 20) * 24;
c = (rand() % 26) + 65;
outtextxy(x, y, c);
}
// 画线擦掉一个像素行
line(0, i, 639, i);
Sleep(10); // 延时
if (i >= 479) i = -1; // 循环处理
if (_kbhit()) break; // 按任意键退出
}
// 关闭图形模式
closegraph();
}
060:画图综合二
题目
画图,综合例子2。
代码实现
C语言
#include <graphics.h>
#include <time.h>
#include <conio.h>
#define MAXSTAR 200 // 星星总数
struct STAR
{
double x;
int y;
double step;
int color;
};
STAR star[MAXSTAR];
// 初始化星星
void InitStar(int i)
{
star[i].x = 0;
star[i].y = rand() % 480;
star[i].step = (rand() % 5000) / 1000.0 + 1;
star[i].color = (int)(star[i].step * 255 / 6.0 + 0.5); // 速度越快,颜色越亮
star[i].color = RGB(star[i].color, star[i].color, star[i].color);
}
// 移动星星
void MoveStar(int i)
{
// 擦掉原来的星星
putpixel((int)star[i].x, star[i].y, 0);
// 计算新位置
star[i].x += star[i].step;
if (star[i].x > 640)
{
InitStar(i);
}
// 画新星星
putpixel((int)star[i].x, star[i].y, star[i].color);
}
// 主函数
int main()
{
srand((unsigned)time(NULL)); // 随机种子
initgraph(640, 480); // 创建绘图窗口
// 初始化所有星星
for (int i = 0; i < MAXSTAR; i++)
{
InitStar(i);
star[i].x = rand() % 640;
}
// 绘制星空,按任意键退出
while (!_kbhit())
{
for (int i = 0; i < MAXSTAR; i++)
{
MoveStar(i);
}
Sleep(20);
}
closegraph(); // 关闭绘图窗口
}
061:杨辉三角
题目
打印出杨辉三角形,10行。格式如下:
**1
1 1
1 2 1
1 3 3 1
1 4 6 4 1**
思路
除1外 其它地方值为它左上角+正上方的值相加
代码实现
C语言
/*
题目:打印出杨辉三角形(要求打印出10行)。
结构如下所示:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
除1外 其它地方值为它左上角+正上方的值相加
*/
#include <stdio.h>
int main() {
int i,j;
int a[10][10];
// 让最左边和对角线上值为1
for(i=0; i<10; i++) {
a[i][0]=1;
a[i][i]=1;
}
// 赋值其它地方 值为它左上角+正上方的值相加
for(i=2; i<10; i++)
for(j=1; j<i; j++)
a[i][j]=a[i-1][j-1]+a[i-1][j];
// 打印
for(i=0; i<10; i++) {
for(j=0; j<=i; j++)
printf("%5d",a[i][j]);
printf("\n");
}
}
062:画点
题目
学习putpixel画点。
代码实现
C语言
#include <graphics.h>
#include <conio.h>
void main()
{
initgraph(800, 600);
for (int i = 0; i < 500; ++i)
{
for (int j = 0; j < 300; ++j)
{
putpixel(i, j, RED);
}
}
getch();
closegraph();
}
063:画椭圆
题目
画椭圆ellipse。
代码实现
C语言
#include <graphics.h>
#include <conio.h>
void main()
{
initgraph(800, 600);
setfillcolor(GREEN);
fillellipse(100, 100, 300, 500);
getch();
closegraph();
}
064:鼠标操作
题目
EasyX 鼠标操作范例
代码实现
C语言
#include <graphics.h>
#include <conio.h>
int main()
{
// 初始化图形窗口
initgraph(640, 480);
MOUSEMSG m; // 定义鼠标消息
while (true)
{
// 获取一条鼠标消息
m = GetMouseMsg();
switch (m.uMsg)
{
case WM_MOUSEMOVE:
// 鼠标移动的时候画红色的小点
putpixel(m.x, m.y, RED);
break;
case WM_LBUTTONDOWN:
// 如果点左键的同时按下了 Ctrl 键
if (m.mkCtrl)
// 画一个大方块
rectangle(m.x - 10, m.y - 10, m.x + 10, m.y + 10);
else
// 画一个小方块
rectangle(m.x - 5, m.y - 5, m.x + 5, m.y + 5);
break;
case WM_RBUTTONUP:
return 0; // 按鼠标右键退出程序
}
}
// 关闭图形窗口
closegraph();
}
065:色彩模型
题目
HSL色彩模型的应用范例。
代码实现
C语言
#include <graphics.h>
#include <conio.h>
int main()
{
// 创建绘图窗口
initgraph(640, 480);
// 画渐变的天空(通过亮度逐渐增加)
float H = 190; // 色相
float S = 1; // 饱和度
float L = 0.7f; // 亮度
for (int y = 0; y < 480; y++)
{
L += 0.0005f;
setlinecolor(HSLtoRGB(H, S, L));
line(0, y, 639, y);
}
// 画彩虹(通过色相逐渐增加)
H = 0;
S = 1;
L = 0.5f;
setlinestyle(PS_SOLID, 2); // 设置线宽为 2
for (int r = 400; r > 344; r--)
{
H += 5;
setlinecolor(HSLtoRGB(H, S, L));
circle(500, 480, r);
}
// 按任意键退出
_getch();
closegraph();
}
066:数字排序
题目
输入3个数a,b,c,按大小顺序输出。
思路
和第五题一样 直接用系统排序 不必多言
代码实现
C语言
/*
输入3个数a,b,c,按大小顺序输出。
*/
#include <stdio.h>
#include <stdlib.h>
int gg(const void* x,const void *y) {
//如果需要从大到小排序则写成return *(int *)y-*(int *)x;
return *(int *)x-*(int *)y;
}
int main() {
int p[10];
int i;
for(i=0; i<3; i++) {
scanf("%d",&p[i]);
}
//自带排序函数 在头文件<stdlib.h>中
qsort(p,3,sizeof(p[0]),gg);
for(i=0; i<3; i++) {
printf("%d ",p[i]);
}
return 0;
}
067:数组交换元素
题目
输入数组,最大的与第一个元素交换,最小的与最后一个元素交换,输出数组。
思路
先找到最大和最小的元素 然后交换(这里使用交换函数完成交换)
代码实现
C语言
/*
输入数组,最大的与第一个元素交换,最小的与最后一个元素交换,输出数组。
*/
#include <stdio.h>
// 交换函数 使用指针接收 需要传入地址 不然无法影响主函数中的变量
void swap(int *a,int *b) {
int t=*a;
*a=*b;
*b=t;
}
int main() {
int p[10]={12,123,4,65,21};
int i,n=5;
// 寻找最大值最小值位置
int mmax = 0,mmin = 0;
for(i=0; i<n; i++) {
if(p[i]>p[mmax]) {
mmax=i;
}
if(p[i]<p[mmin]) {
mmin=i;
}
}
// 交换
swap(&p[0],&p[mmax]);
swap(&p[n-1],&p[mmin]);
// 打印
for(i=0; i<n; i++) {
printf("%d ",p[i]);
}
return 0;
}
068:调整位置
题目
有n个整数,使其前面各数顺序向后移m个位置,最后m个数变成最前面的m个数。
思路
这道题有很多种思路 详见我之前发的文章 1046: [编程入门]自定义函数之数字后移
代码实现
C语言
/*
有n个整数,使其前面各数顺序向后移m个位置,最后m个数变成最前面的m个数。
*/
#include <stdio.h>
int main() {
int i,j=0;
int x,n;
int p[1007]= {0};
scanf("%d",&n);
for(i=0; i<n; i++) {
scanf("%d",&p[i]);
}
scanf("%d",&x);
for(i=x+n-1; i>=0; i--) { //全部移动x位
p[i]=p[i-x];
}
//后面的移到前面来
j=n;
for(i=0; i<x; i++,j++) {
p[i]=p[j];
}
for(i=0; i<n; i++) {
printf("%d ",p[i]);
}
return 0;
}
069:报数问题
题目
有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
思路
报数问题也就是约瑟夫环,用链表或数组都可以
代码实现
C语言
/*
有n个人围成一圈,顺序排号。
从第一个人开始报数(从1到3报数)
凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
报数问题也就是约瑟夫环,用链表或数组都可以
*/
#include <stdio.h>
#include <stdlib.h>
typedef struct node { //定义一个结构体,中间存放下一位置的指针以及数据
int data;
struct node *next;
} Node,*List;
List Init_list(int n) { //初始化表,传入的n为所要求的人数
int i;
Node *t = (Node *)malloc(sizeof(Node)); //创建一个指针t,t指针的数据域不赋值,用来作为移动的指针
t->next = NULL;
List head = t; //定义一个头节点,存放指针t的地址,为了最后一个节点指向头节点的后一个数据,也就是1的位置
for(i=1; i<=n; i++) {
Node *temp = (Node *)malloc(sizeof(Node)); //创建一个指针temp,放入对应数据
temp->data = i;
temp->next = NULL;
t->next = temp; //将temp插入t指针的指针域中
t = temp; //插完之后t指针应该指向temp的内存地址为了下一次能够继续插入
}
t->next = head->next; //此时的t作为尾节点,其指针指向1(也就是head->next)
return head;
}
void find_del(List head,int m,int k) { //找数并且删除,直到最后一个数据 ,head为链表头节点,m为第几个开始,k为报数
Node *p,*t; //这里定义两个指针,p指向正在报数的地址,t指向p的前驱节点
int i;
p = head;
for(i=1; i<=m; i++) { //这里做的是定位到第几个数据开始报 ,
t = p; //每循环一次t指向p,p指向下一个节点
p = p->next;
}
while(p!=p->next) { //因为是循环链表,当链表中数据只剩下一个时,它对应的指针域应该指向它自己
for(i=1; i<k; i++) { //根据k进行移动,因为每一节点的指针域都指向对应节点,就不用像数组一样要考虑最后一个节点指向哪里
t = p;
p = p->next;
}
t->next = p->next; //此时p指向报到k的的地址,t为p的前驱节点,也就是前面一个,这时我们要删除的是p所指的节点,(连接下面,写满了)
free(p); //那么只需要将指针t的下一节点改为p的下一节点指针域,并且free(p),也就是删除p指针的数据
p = t->next; //这时p指针中为空,那么将p指向t的指针域也就移动到删除数的后面一节点了
}
printf("%d",p->data); //while出来,即为所剩下来的数据
free(p);
p = NULL;
}
//使用数组解决
void run() {
int n,j,i,current = -1;
int a[1007];
scanf("%d",&n);
for(i=1; i<=n; i++) //将初始的数按1,2,3放入数组中
a[i-1] = i;
while(n!=1) { //当总数为1时说明数组中只剩下一人
for(j=1; j<=3; j++)
current = (current+1)%n; //current作为报数的下标
for(j=current+1; j<n; j++) //将下标后面的值依次往前移
a[j-1] = a[j];
current--; //去掉一个数后报数下标也要往前移一次
n--; //总人数减去1
}
printf("%d",a[0]); //打印最后留在a[0]或者a[current+1]中的数即为最后一人
}
int main() {
int n;
scanf("%d",&n);
List head = (Node *)malloc(sizeof(Node));
head = Init_list(n);
find_del(head,1,3);
// run();
return 0;
}
070:求字符串长度
题目
写一个函数,求一个字符串的长度,在main函数中输入字符串,并输出其长度。
思路
字符串最后默认自带\0作为结束
代码实现
C语言
/*
写一个函数,求一个字符串的长度,在main函数中输入字符串,并输出其长度。
*/
#include <stdio.h>
#include <string.h>
//求字符串长度
//字符串最后默认自带\0作为结束
int length(char *s) {
int i=0;
while(*s++!='\0') {
i++;
}
return i;
}
int main() {
int len;
char str[20];
scanf("%s",str);
// 使用string.h库里面的strlen函数
// len=strlen(str);
// 自己完成函数
len=length(str);
printf("%d",len);
}
071:结构体的输入输出
题目
编写input()和output()函数输入,输出5个学生的数据记录(学生姓名、性别、年龄)。
思路
这道题考察结构体的使用,对于结构体来说普通变量使用.来取出,指针变量使用->
代码实现
C语言
/*
编写input()和output()函数输入,输出5个学生的数据记录(学生姓名、性别、年龄)
这道题考察结构体的使用,对于结构体来说普通变量使用.来取出,指针变量使用->
*/
#include <stdio.h>
// 定义学生结构体
struct Student {
char name[50];
char gender;
int age;
};
// input函数用于输入学生数据
void input(struct Student students[], int count) {
int i;
for (i = 0; i < count; i++) {
scanf("%s", students[i].name);
scanf("%c", &students[i].gender);
scanf("%d", &students[i].age);
}
}
// output函数用于输出学生数据
void output(struct Student students[], int count) {
int i;
for (i = 0; i < count; i++) {
printf("姓名: %s\n", students[i].name);
printf("性别: %c\n", students[i].gender);
printf("年龄: %d\n", students[i].age);
}
}
int main() {
const int n = 5;
struct Student students[n];
// 输入学生数据
input(students, n);
// 输出学生数据
output(students, n);
return 0;
}
072:创建链表
题目
创建一个链表。
代码实现
C语言
/*
创建一个链表
*/
#include <stdio.h>
#include <malloc.h>
struct LNode {
int data;
struct LNode *next;
};
struct LNode* createList(int n) {
struct LNode *list, *p, *q;
list = (struct LNode*)malloc(sizeof(struct LNode));
list->next = NULL;
q = list;
int i;
for (i = 0; i < n; ++i) {
p = (struct LNode*)malloc(sizeof(struct LNode));
printf("请输入第%d个元素的值:", i + 1);
scanf("%d", &(p->data));
p->next = NULL;
q->next = p;
q = p;
}
return list;
}
void print(struct LNode* list) {
printf("链表各值为:\n");
struct LNode* p = list->next;
while (p != NULL) {
printf("%d\n", p->data);
p = p->next;
}
}
int main() {
struct LNode* list = NULL;
int n;
scanf("%d", &n);
list = createList(n);
print(list);
return 0;
}
073:反序输出链表
题目
反向输出一个链表。
代码实现
C语言
/*
反向输出一个链表。
*/
#include <stdio.h>
#include <malloc.h>
typedef struct LNode {
int data;
struct LNode *next;
} LNode;
LNode* createList(int n) {
LNode *head, *p, *q;
head = (LNode*)malloc(sizeof(LNode));
printf("请输入第1个元素的值:");
scanf("%d", &(head->data));
head->next = NULL;
q = head;
int i;
for (i = 1; i < n; ++i) {
p = (LNode*)malloc(sizeof(LNode));
printf("请输入第%d个元素的值:", i + 1);
scanf("%d", &(p->data));
p->next = q;
q = p;
}
return q;
}
void print(LNode* list) {
printf("链表各值为:\n");
LNode* p = list;
while (p != NULL) {
printf("%d\n", p->data);
p = p->next;
}
}
int main() {
int n;
scanf("%d", &n);
LNode* list = createList(n);
print(list);
return 0;
}
074:连接两个链表
题目
连接两个链表。
代码实现
C语言
/*
连接两个链表。
*/
#include <stdio.h>
#include <malloc.h>
typedef struct LNode {
int data;
struct LNode *next;
} LNode;
LNode* createList(int n) {
LNode *list, *p, *q;
list = (LNode*)malloc(sizeof(LNode));
list->next = NULL;
q = list;
int i;
for (i = 0; i < n; ++i) {
p = (LNode*)malloc(sizeof(LNode));
printf("请输入第%d个元素的值:", i + 1);
scanf("%d", &(p->data));
p->next = NULL;
q->next = p;
q = p;
}
return list;
}
void print(LNode* list) {
printf("链表各值为:\n");
LNode* p = list->next;
while (p != NULL) {
printf("%d\n", p->data);
p = p->next;
}
}
void connect(LNode* list1, LNode* list2) {
LNode* p;
for (p = list1; p->next != NULL; p = p->next) {
continue;
}
p->next = list2->next;
free(list2);
}
int main() {
int n;
scanf("%d", &n);
LNode* list1 = createList(n);
LNode* list2 = createList(n);
connect(list1, list2);
print(list1);
return 0;
}
075:数字反转
题目
输入一个整数,并将其反转后输出。
思路
方法一 使用%10得到最低位数字
方法二 看成字符串,变成第35题字符串反转
代码实现
C语言
/*
输入一个整数,并将其反转后输出。
方法一 使用%10得到最低位数字
方法二 看成字符串,变成第35题字符串反转
*/
#include <stdio.h>
int main() {
int n;
scanf("%d",&n);
int m=0;
while(n) {
m*=10; // 注意这条语句的位置
m+=n%10;
n/=10;
}
printf("%d",m);
return 0;
}
076:指针函数
题目
编写一个函数,输入n为偶数时,调用函数求1/2+1/4+...+1/n,当输入n为奇数时,调用函数1/1+1/3+...+1/n(利用指针函数)。
思路
这道题的重点是指针函数的使用
代码实现
C语言
/*
编写一个函数,输入n为偶数时,调用函数求1/2+1/4+...+1/n
当输入n为奇数时,调用函数1/1+1/3+...+1/n(利用指针函数)。
这道题的重点是指针函数的使用
*/
#include <stdio.h>
double evenumber(int n) {
double s=0,a=0;
int i;
for(i=2; i<=n; i+=2) {
a=(double)1/i;
s+=a;
}
return s;
}
double oddnumber(int n) {
double s=0,a=0;
int i;
for(i=1; i<=n; i+=2) {
a=(double)1/i;
s+=a;
}
return s;
}
int main() {
int n;
double r;
// 重点 声明指针函数写法函数类型、指针、所需参数类型
double (*pfunc)(int);
scanf("%d",&n);
// 赋值的是函数名
if(n%2==0) pfunc=evenumber;
else pfunc=oddnumber;
r=(*pfunc)(n);
printf("%lf\n",r);
return 0;
}
077:二重指针
题目
指向指针的指针。
思路
对于字符串数组有两种写法
代码实现
C语言
/*
指向指针的指针
*/
#include <stdio.h>
int main() {
// 对于字符串数组有两种写法
// char s[][10]= {"man","woman","girl","boy","sister"};
char *s[] = {"man","woman","girl","boy","sister"};
char **q;
int i;
for(i=0; i<5; i++) {
q=s[i];
printf("%s\n",q);
}
return 0;
}
078:找到最大的人
题目
找到年龄最大的人,并输出。
代码实现
C语言
/*
找到年龄最大的人,并输出。
*/
#include <stdio.h>
struct man {
char name[20];
int age;
}
person[3]= {"li",18,"wang",25,"sun",22};
int main() {
struct man *q,*p;
int i,m=0;
p=person;
for(i=0; i<3; i++) {
if(m < p->age) {
m=p->age;
q=p;
}
p++;
}
printf("%s %d\n",q->name,q->age);
return 0;
}
079:字符串排序
题目
字符串排序
代码实现
C语言
/*
字符串排序
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int gg(const void *x,const void *y) {
char **a = x;
char **b = y;
return strcmp(a,b);
}
int main() {
int i,n=5;
char p[][10] = {"man","woman","girl","boy","sister"};
qsort(p,n,sizeof(p[0]),gg);
for(i=0; i<n; i++) {
printf("%s\n",p[i]);
}
return 0;
}
080:猴子分桃子
题目
海滩上有一堆桃子,五只猴子来分。第一只猴子把这堆桃子平均分为五份,多了一个,这只 猴子把多的一个扔入海中,拿走了一份。第二只猴子把剩下的桃子又平均分成五份,又多了 一个,它同样把多的一个扔入海中,拿走了一份,第三、第四、第五只猴子都是这样做的, 问海滩上原来最少有多少个桃子?
思路
注意:最后一只猴子不一定剩1个哦
代码实现
C语言
/*
海滩上有一堆桃子,五只猴子来分。
第一只猴子把这堆桃子平均分为五份,多了一个,这只猴子把多的一个扔入海中,拿走了一份。
第二只猴子把剩下的桃子又平均分成五份,又多了 一个,它同样把多的一个扔入海中,拿走了一份
第三、第四、第五只猴子都是这样做的, 问海滩上原来最少有多少个桃子?
注意:最后一只猴子不一定剩1个哦
*/
#include <stdio.h>
int main() {
int x; // 桃子总数
int i = 0; // 循环轮数
int j = 1; // 暂存每轮尝试的起始e的倍数
while (1) {
x = 4 * j; // 拟定起始e的值
for (i = 0; i < 5; i++) { // 一共五只猴子,五轮循环
if (x % 4 != 0) { // 最后一只猴子待分配的桃子数一定能被4整除
break; // 若在5轮中某一轮不能被4整除,则要重新更换起始e的值
}
x = (x/4)*5+1; // 向上递归累加
}
if(i>=5)break;
j++; // 通过递增j来更换4的倍数,从而重新更换起始e的值
}
printf("%d\n", x);
return 0;
}
081:补全算式
题目
809*??=800*??+9*?? 其中??代表的两位数, 809*??为四位数,8*??的结果为两位数,9*??的结果为3位数。求??代表的两位数,及809*??后的结果。
思路
这道题我真是做笑了,看起来像乱码一样
代码实现
C语言
/*
809*??=800*??+9*?? 其中??代表的两位数,
809*??为四位数,8*??的结果为两位数,9*??的结果为3位数。
求??代表的两位数,及809*??后的结果
*/
#include <stdio.h>
int main() {
int a,b,i;
for(i = 10; i < 100; i++) {
b = i * 809;
//条件一 809*??=800*??+9*??
if (b==800*i+9*i) {
// 条件二 809*??为四位数,8*??的结果为两位数,9*??的结果为3位数
if(b >= 1000 && b <= 10000 && 8 * i < 100 && 9 * i >= 100) {
printf("%d = 800 * %d + 9 * %d\n", b,i,i);
}
}
}
return 0;
}
082:八进制转十进制
题目
八进制转换为十进制。
思路
思路一 使用按权展开求十进制
思路二 当成字符串使用按权展开
代码实现
C语言
/*
八进制转换为十进制。
思路一 使用按权展开求十进制
思路二 当成字符串使用按权展开
*/
#include <stdio.h>
void run1() {
int n,k=1,z=0;
scanf("%d",&n);
while(n) {
z+=n%10*k;
k*=8;
n/=10;
}
printf("%d",z);
}
void run2() {
int i,z=0;
char s[20];
gets(s);
while(s[i]!='\0') {
z=z*8+s[i]-'0';
i++;
}
printf("%d",z);
}
int main() {
run1();
// run2();
return 0;
}
083:组成奇数个数
题目
求0—7所能组成的奇数个数。
思路
a1-a8可以取 0-7 这个八个数字,首位数字不为 0。
从该数为一位数到该数为8位数开始统计奇数的个数:
1.当只有一位数时也就是该数的最后一位,奇数个数为4
2.当该数为两位数时,奇数个数为4*7=28
3.当该数为三位数时,奇数个数为:4*8*7=224
...
8.当该数为八位数时,奇数个数为:4*8*8*8*8*8*8*7(依次为最后一位到第一位)
代码实现
C语言
/*
题目:求0—7所能组成的奇数个数。
程序分析:
a1-a8可以取 0-7 这个八个数字,首位数字不为 0。
从该数为一位数到该数为8位数开始统计奇数的个数:
1.当只有一位数时也就是该数的最后一位,奇数个数为4
2.当该数为两位数时,奇数个数为4*7=28
3.当该数为三位数时,奇数个数为:4*8*7=224
...
8.当该数为八位数时,奇数个数为:4*8*8*8*8*8*8*7(依次为最后一位到第一位)
*/
#include <stdio.h>
int main() {
long sum = 4, s = 4;//sum的初始值为4表示,只有一位数字组成的奇数个数为4个
int j;
for (j = 2; j <= 8; j++) {
printf("%d位数为奇数的个数%ld\n", j-1, s);
if (j <= 2)
s *= 7;
else
s *= 8;
sum += s;
}
printf("%d位数为奇数的个数%ld\n", j-1, s);
printf("奇数的总个数为:%ld\n", sum);
return 0;
}
084:分解偶数
题目
一个偶数总能表示为两个素数之和。给出一个偶数,请把它分解成两个素数。
思路
素数|质数的问题很重要呀!
重点代码是这一行:if(vis(i)&&vis(n-i))
代码实现
C语言
/*
一个偶数总能表示为两个素数之和。给出一个偶数,请把它分解成两个素数。
素数|质数的问题很重要呀!
重点代码是这一行:if(vis(i)&&vis(n-i))
*/
#include <stdio.h>
int vis(int n) {
if(n<2)return 0;
int i=2;
for(i=2; i<n; i++) {
if(n%i==0)return 0;
}
return 1;
}
int main(){
int n;
scanf("%d",&n);
int i;
for(i=2;i<n;i++){
if(vis(i)&&vis(n-i)){
printf("%d = %d + %d\n",n,i,n-i);
}
}
return 0;
}
085:素数整除
题目
判断一个素数能整除几个9组成的数,例如:
素数13能整除6个9组成的数999999
代码实现
C语言
/*
判断一个素数能整除几个9组成的数,例如:
素数13能整除6个9组成的数9999994
*/
#include <stdio.h>
int main() {
int p,i=0;
int sum=9;
scanf("%d",&p);
while(++i) {
if(sum%p==0)break;
else sum=sum*10+9;
}
printf("素数%d能整除%d个9组成的数%ld\n",p,i,sum);
return 0;
}
086:字符串连接
题目
将两个字符串连接。
思路
因为c语言不能像c++的string一样直接赋值,所以需要单个赋值
思路一 使用string库的strcat函数拼接
思路二 使用自定义函数拼接
注意 都需要保证内存大于两个字符串
代码实现
C语言
/*
将两个字符串连接。
因为c语言不能像c++的string一样直接赋值,所以需要单个赋值
思路一 使用string库的strcat函数拼接
思路二 使用自定义函数拼接
注意 都需要保证内存大于两个字符串
*/
#include <stdio.h>
#include <stdlib.h>// malloc申请内存函数在stblib.h库中
#include <string.h>
// 自定义实现 strcat 函数
void charcat(char *str,char *str1) {
while(*str!='\0')str++;
while(*str1!='\0') {
*str = *str1;
str++;
str1++;
}
// 注意最后加上\0
*str = '\0';
}
char* strconnect(char *str1,char *str2) {
char *str;
// 需要保证内存大于两个字符串
str=(char*)malloc(strlen(str1)+strlen(str2)+1);
str[0] = '\0';
// strcat(str,str1);
// strcat(str,str2);
charcat(str,str1);
charcat(str,str2);
return str;
}
int main() {
char str1[20],str2[20];
char *str;
scanf("%s%s", str1, str2);
str = strconnect(str1,str2);
puts(str);
return 0;
}
087:回答结果
题目
回答结果(不运行程序,写出程序的结果)
思路
提示 函数不传指针或者地址 都是形参
代码实现
C语言
/*
回答结果(不运行程序,写出程序的结果)
提示 函数不传指针或者地址 都是形参
*/
#include <stdio.h>
struct student {
int x;
char c;
} a;
void f(struct student b) {
b.x = 555;
b.c = 'w';
}
int main() {
a.x = 4;
a.c = 'b';
f(a);
printf("%d,%c", a.x, a.c);
return 0;
}
088:打印星号
题目
读取7个数(1—50)的整数值,每读取一个值,程序打印出该值个数的*。
思路
在考察循环的嵌套 , 使用while和for都可以做
代码实现
C语言
/*
读取7个数(1—50)的整数值,每读取一个值,程序打印出该值个数的*。
在考察循环的嵌套 , 使用while和for都可以做
*/
#include <stdio.h>
int main() {
int n=7,i,m;
// 循环七次
while(n--){
scanf("%d",&m);
for(i=0;i<m;i++){
printf("*");
}
printf("\n");
}
return 0;
}
089:电话加密
题目
某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的,加密规则如下: 每位数字都加上5,然后用和除以10的余数代替该数字,再将第一位和第四位交换,第二位和第三位交换。
思路
将数字拆分成数组,便于操作每一位上的数
代码实现
C语言
/*
某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的,
加密规则如下: 每位数字都加上5,然后用和除以10的余数代替该数字,
再将第一位和第四位交换,第二位和第三位交换。
*/
#include <stdio.h>
void swap(int *a,int *b) {
int t = *a;
*a = *b;
*b = t;
}
int main() {
int i,n,p[4];
scanf("%d",&n);
// 将这四位数放到数组里面
for(i=3; n!=0; i--) {
// 得到这一位上的数 +5 然后对10取余
p[i] = (n%10+5)%10;
n/=10;
}
// 交换14位和23位
swap(&p[0],&p[3]);
swap(&p[1],&p[2]);
//打印
for(i=0; i<4; i++) {
printf("%d",p[i]);
}
return 0;
}
090:读结果
题目
读结果。(说出程序的结果)
代码实现
C语言
/*
读结果。(说出程序的结果)
提示
t=*(a+i);
*(a+i)=*(a+j);
*(a+j)=t;
就是交换操作
*/
#include <stdio.h>
#define M 5
int main() {
int a[M]= {1,2,3,4,5};
int i,j,t;
i=0;
j=M-1;
while(i<j) {
t=*(a+i);
*(a+i)=*(a+j);
*(a+j)=t;
i++;
j--;
}
for(i=0; i<M; i++) {
printf("%d\n",*(a+i));
}
return 0;
}
091:时间函数一
题目
打印本地时间
代码实现
C语言
/*
打印本地时间
*/
#include <stdio.h>
#include <time.h>
int main () {
time_t rawtime;
struct tm * timeinfo;
time ( &rawtime );
timeinfo = localtime ( &rawtime );
printf ( "当前本地时间为: %s", asctime (timeinfo) );
return 0;
}
092:时间函数二
题目
返回两个time\_t型变量之间的时间间隔
代码实现
C语言
/*
返回两个time_t型变量之间的时间间隔
*/
#include <stdio.h>
#include <time.h>
int main() {
time_t start,end;
int i;
start=time(NULL);
for(i=0; i<33000; i++) {
printf("*");
}
end=time(NULL);
// 输出执行时间
// 返回两个time_t型变量之间的时间间隔
printf("时间间隔为 %6.3f\n",difftime(end,start));
}
093:时间函数三
题目
计算n次循环的耗时
代码实现
C语言
/*
计算n次循环的耗时
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
long i=10000000L;
clock_t start,finish;
double TheTimes;
printf("做%ld次空循环需要的时间为",i);
start=clock();
while(i--);
finish=clock();
TheTimes=(double)(finish-start)/CLOCKS_PER_SEC;
printf("%f秒。\n",TheTimes);
return 0;
}
094:猜谜游戏
题目
猜谜游戏。(编写一个数字猜谜程序)
代码实现
C语言
/*
猜谜游戏。(编写一个数字猜谜程序)
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void game(void) {
int n;
char begin;
int count = 1;
srand((int)time(NULL));
int m = (rand() % 100) + 1;
puts("游戏开始,请输入数字:");
while (1) {
scanf("%d", &n);
if (n == m) {
printf("猜中了,使用了 %d 次!\n", count);
if (count == 1) {
printf("你是神级人物了!膜拜\n");
getchar();
printf("你已经达到最高级别,还需要玩吗?Y/N \n");
scanf("%c", &begin);
if (begin == 'Y' || begin == 'y') { //重复玩的一个嵌套循环
game();
} else {
printf("谢谢,再见!\n");
}
} else if (count <= 5) {
printf("你是王级人物了!非常赞\n");
getchar();
printf("需要挑战最高级别不?Y/N \n");
scanf("%c", &begin);
if (begin == 'Y' || begin == 'y') {
game();
} else {
printf("谢谢,再见!\n");
}
} else if (count <= 10) {
printf("你是大师级人物了!狂赞\n");
getchar();
printf("需要挑战最高级别不?Y/N \n");
scanf("%c", &begin);
if (begin == 'Y' || begin == 'y') {
game();
} else {
printf("谢谢,再见!\n");
}
} else if (count <= 15) {
printf("你是钻石级人物了!怒赞\n");
getchar();
printf("需要挑战最高级别不?Y/N \n");
scanf("%c", &begin);
if (begin == 'Y' || begin == 'y') {
game();
} else {
printf("谢谢,再见!\n");
}
} else {
getchar();
printf("你的技术还有待提高哦!重玩? Y/N\n");
scanf("%c", &begin);
if (begin == 'Y' || begin == 'y') {
game();
} else {
printf("谢谢,再见!\n");
}
}
break;
} else if (n < m) {
puts("太小了!");
puts("重新输入:");
} else {
puts("太大了!");
puts("重新输入:");
}
count++;//计数器
}
}
int main(void) {
game();
return 0;
}
095:简单结构体
题目
简单的结构体应用实例。(实现结构体的赋值)
代码实现
C语言
/*
简单的结构体应用实例。(实现结构体的赋值)
*/
#include <stdio.h>
struct programming {
float constant;
char *pointer;
};
int main() {
struct programming variable;
char string[] = "指针原来是套娃的";
variable.constant = 1.23;
variable.pointer = string;
printf("%f\n", variable.constant);
printf("%s\n", variable.pointer);
return 0;
}
096:子串个数
题目
计算字符串中子串出现的次数。
请输入两个字符串,以回车隔开,母串在前,子串在后:
abca
a
输出:2
代码实现
C语言
/*
计算字符串中子串出现的次数。
输入两个字符串,以回车隔开,母串在前,子串在后:
abca
a
输出:2
*/
#include <stdio.h>
#include <string.h>
int subString(char *str,char *sub) {
int count = 0, i, j;
for (i = 0; i < strlen(str); i++) {
for (j = 0; j < strlen(sub); j++) {
if(str[i + j] != sub[j]) {
break; // 出现了不同字符就退出循环
}
}
if (j == strlen(sub)) {
count++; // 退出循环后若j的值等于子串的长度,则存在子串
}
}
return count;
}
int main(void) {
char str[100],sub[50];
printf("请输入母串:");
gets(str);
printf("请输入子串:");
gets(sub);
printf("%d", subString(str,sub));
return 0;
}
097:文件写入
题目
从键盘输入一些字符,逐个把它们送到磁盘文件97.txt上去,直到输入一个#为止。
思路
fopen是一个用于打开文件的函数。
这个函数需要两个参数:第一个是文件名(通常是一个字符串),
第二个是模式(也是一个字符串),用于指定文件应该如何被打开。
第二个参数可选 :
"r": 读取模式。打开文件进行读取。如果文件不存在,会返回错误。
"w": 写入模式。如果文件存在,则清空文件内容;如果文件不存在,则创建新文件。
"a": 追加模式。如果文件存在,则在文件末尾追加内容;如果文件不存在,则创建新文件用于写入。
"r+": 读写模式。打开文件进行读取和写入。文件必须存在,否则会返回错误。
"w+": 读写模式。如果文件存在,则清空文件内容;如果文件不存在,则创建新文件。允许读写操作。
"a+": 读写模式。如果文件存在,则在文件末尾追加内容;如果文件不存在,则创建新文件用于写入。允许读写操作,但写入操作总是在文件末尾进行。
"x": 创建并写入模式。如果文件存在,则打开失败;如果文件不存在,则创建新文件用于写入。这是POSIX标准中的一个模式,不是所有系统都支持。
"x+": 创建并读写模式。如果文件存在,则打开失败;如果文件不存在,则创建新文件用于读写。这同样是POSIX标准中的一个模式,不是所有系统都支持。
注意,除了基本的读写模式之外,你还可以在这些模式后面添加一些额外的修饰符,例如:
"b": 二进制模式(binary mode)。在Windows平台上,这会影响文件的打开方式,使其以二进制方式处理,而不是文本方式。在其他系统上,这个修饰符可能没有效果。
例如,"rb" 表示以二进制模式打开文件进行读取,"wb" 表示以二进制模式打开文件进行写入。
fputc函数放一个字符串到文件内
fclose(file);函数关闭文件流
代码实现
C语言
/*
从键盘输入一些字符,逐个把它们送到磁盘文件97.txt上去,直到输入一个#为止。
fopen是一个用于打开文件的函数。
这个函数需要两个参数:第一个是文件名(通常是一个字符串),
第二个是模式(也是一个字符串),用于指定文件应该如何被打开。
第二个参数可选 :
"r": 读取模式。打开文件进行读取。如果文件不存在,会返回错误。
"w": 写入模式。如果文件存在,则清空文件内容;如果文件不存在,则创建新文件。
"a": 追加模式。如果文件存在,则在文件末尾追加内容;如果文件不存在,则创建新文件用于写入。
"r+": 读写模式。打开文件进行读取和写入。文件必须存在,否则会返回错误。
"w+": 读写模式。如果文件存在,则清空文件内容;如果文件不存在,则创建新文件。允许读写操作。
"a+": 读写模式。如果文件存在,则在文件末尾追加内容;如果文件不存在,则创建新文件用于写入。允许读写操作,但写入操作总是在文件末尾进行。
"x": 创建并写入模式。如果文件存在,则打开失败;如果文件不存在,则创建新文件用于写入。这是POSIX标准中的一个模式,不是所有系统都支持。
"x+": 创建并读写模式。如果文件存在,则打开失败;如果文件不存在,则创建新文件用于读写。这同样是POSIX标准中的一个模式,不是所有系统都支持。
注意,除了基本的读写模式之外,你还可以在这些模式后面添加一些额外的修饰符,例如:
"b": 二进制模式(binary mode)。在Windows平台上,这会影响文件的打开方式,使其以二进制方式处理,而不是文本方式。在其他系统上,这个修饰符可能没有效果。
例如,"rb" 表示以二进制模式打开文件进行读取,"wb" 表示以二进制模式打开文件进行写入。
fputc函数放一个字符串到文件内
fclose(file);函数关闭文件流
*/
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE*fp = NULL;
char ch;
if ((fp = fopen("97.txt", "w")) == NULL) {
printf("ERROR!\n");
exit(0);
}
printf("输入字符,以#结束:\n");
getchar();
while ((ch = getchar()) != '#') {
fputc(ch, fp);
}
fclose(fp);
return 0;
}
098:字母转换
题目
从键盘输入一个字符串,将小写字母全部转换成大写字母,然后输出到一个磁盘文件"98.txt"中保存。
思路
fprintf(fp,"%s",str);
fp为文件 %s输出格式 str是字符串 这样就将str的内容以字符串的形式存入了文件中
代码实现
C语言
/*
从键盘输入一个字符串,将小写字母全部转换成大写字母,然后输出到一个磁盘文件"98.txt"中保存。
fprintf(fp,"%s",str);
fp为文件 %s输出格式 str是字符串 这样就将str的内容以字符串的形式存入了文件中
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
FILE*fp=NULL;
char str[50];
int i,len;
printf("输入一个字符串:\n");
gets(str);
len=strlen(str);
// 小写转大写 这里用到ASCII值
for(i=0; i<len; i++) {
if(str[i]<='z'&&str[i]>='a')
str[i]-=32;
}
if((fp=fopen("98.txt","w"))==NULL) {
printf("error: cannot open file!\n");
exit(0);
}
fprintf(fp,"%s",str);
fclose(fp);
return 0;
}
099:文件合并
题目
有两个磁盘文件97.txt和98.txt,各存放一行文字
要求把这两个文件中的信息合并,输出到一个新文件C中。
代码实现
C语言
/*
有两个磁盘文件97.txt和98.txt,各存放一行文字
要求把这两个文件中的信息合并,输出到一个新文件C中。
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
FILE *fa,*fb,*fc;
int i,j,k;
char str[100],str1[100];
char tem;
if((fa=fopen("97.txt","r"))==NULL) { // 97.txt 文件需要存在
printf("error: cannot open A file!\n");
exit(0);
}
fgets(str,99,fa);
fclose(fa);
if((fb=fopen("98.txt","r"))==NULL) { // 98.txt 文件需要存在
printf("error: cannot open B file!\n");
exit(0);
}
fgets(str1,99,fb);
fclose(fb);
// 拼接两个字符串
strcat(str,str1);
if((fc=fopen("99.txt","w"))==NULL) { // 合并为 99.txt
printf("error: cannot open C file!\n");
exit(0);
}
fputs(str,fc);
fclose(fc);
return 0;
}
100:计算成绩
题目
有五个学生,每个学生有3门课的成绩,从键盘输入以上数据(包括学生号,姓名,三门课成绩),计算出平均成绩,况原有的数据和计算出的平均分数存放在磁盘文件"stud"中。
代码实现
C语言
/*
有五个学生,每个学生有3门课的成绩,从键盘输入以上数据(包括学生号,姓名,三门课成绩)
请你计算出平均成绩,将原有的数据和计算出的平均分数存放在磁盘文件"100.txt"中。
*/
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int ID;
int math;
int English;
int C;
int avargrade;
char name[20];
} Stu;
int main() {
FILE*fp;
Stu stu[5];
int i,avargrade=0;
printf("请输入5个同学的信息:学生号,姓名,3门成绩:\n");
for(i=0; i<5; i++) {
scanf("%d %s %d %d %d",&(stu[i].ID),stu[i].name,&(stu[i].math),&(stu[i].English),&(stu[i].C));
stu[i].avargrade=(stu[i].math+stu[i].English+stu[i].C)/3;
}
if((fp=fopen("100.txt","w"))==NULL) {
printf("error :cannot open file!\n");
exit(0);
}
for(i=0; i<5; i++)
fprintf(fp,"%d %s %d %d %d %d\n",stu[i].ID,stu[i].name,stu[i].math,stu[i].English,
stu[i].C,stu[i].avargrade);
fclose(fp);
return 0;
}
评论