C语言经典题目详解(PTA题目)
一.四数立方和问题
#include<stdio.h>
int main(){
int N; // 定义变量N,用来存储输入的最大数字
int a, b, c, d; // 定义四个变量a, b, c, d,用来遍历所有的组合
scanf("%d", &N); // 输入一个整数N
// 外层循环,a从2到N
for(a = 2; a <= N; a++) {
// 第二层循环,b从2到N-1
for(b = 2; b < N; b++) {
// 第三层循环,c从b到N-1,确保c >= b,避免重复组合
for(c = b; c < N; c++) {
// 第四层循环,d从c到N-1,确保d >= c,避免重复组合
for(d = c; d < N; d++) {
// 如果a^3等于b^3 + c^3 + d^3,打印四个数字
if(a * a * a == b * b * b + c * c * c + d * d * d) {
// 打印符合条件的a, b, c, d四个数字
printf("%d %d %d %d\n", a, b, c, d);
}
}
}
}
}
return 0; // 返回0,表示程序结束
}
二.你会计算时间复杂度吗?

#include<stdio.h>
int main() {
// 声明一个字符数组用来存储输入的字符串,最大长度为1000000
char str[1000000];
// 读取输入的代码字符串,格式是由 "for" 和 "end" 组成
scanf("%s", str);
getchar(); // 读取剩余的换行符
// 用来存储当前循环的深度
int maxshen = 0;
// 用来计算嵌套的for循环深度
int count = 0;
// 遍历字符串中的每个字符
for (int i = 0; str[i] != '\0'; i++) {
// 检查是否遇到 "for"
if (str[i] == 'f' && str[i + 1] == 'o' && str[i + 2] == 'r') {
count++; // 深度增加
if (count > maxshen) { // 更新最大深度
maxshen = count;
}
}
// 检查是否遇到 "end"
else if (str[i] == 'e' && str[i + 1] == 'n' && str[i + 2] == 'd') {
count--; // 深度减少
}
// 跳过 "for" 和 "end" 的字符,确保在下一次迭代时不会重复计算
i += 2;
}
// 输出根据最大深度计算的时间复杂度
if (maxshen == 1) {
printf("O(n)"); // 如果最大深度是1,时间复杂度为 O(n)
} else {
printf("O(n^%d)", maxshen); // 如果最大深度大于1,输出 O(n^depth)
}
return 0;
}
三.判断完全平方数
#include <stdio.h>
#include <math.h>
// 判断是否为完全平方数
int IsSquare(int n) {
if (n < 0) return 0; // 负数不是完全平方数
int sqrt_n = (int)sqrt(n); // 计算平方根并强制转换为整数
if (sqrt_n * sqrt_n == n) // 判断平方根的平方是否等于原数
return 1;
else
return 0;
}
int main() {
int n;
scanf("%d", &n);
if (IsSquare(n))
printf("YES\n");
else
printf("NO\n");
return 0;
}
四.求余弦函数的近似值
#include <stdio.h>
// 计算 cos(x) 的近似值
double funcos(double e, double x) {
double cosx = 1.0; // 初始项
double term = 1.0; // 当前项的值
int n = 1; // 计数器,用于更新分子和分母
while (1) {
// 计算当前项
term *= -(x * x) / (n * (n + 1)); // 递推公式
n += 2; // 阶数加 2
// 累加结果
cosx += term;
// 检查绝对值是否小于误差上限
if (term > -e && term < e) {
break;
}
}
return cosx;
}
int main() {
double e, x;
scanf("%lf %lf", &e, &x);
printf("cos(%.2f) = %.6f\n", x, funcos(e, x));
return 0;
}
五. 使用函数输出指定范围内的Fibonacci数
#include <stdio.h>
// 计算第 n 项的 Fibonacci 数
int fib(int n) {
int arr[100]; // 缓存前 100 项 Fibonacci 数
arr[0] = 1;
arr[1] = 1;
for (int i = 2; i < 100; i++) {
arr[i] = arr[i - 1] + arr[i - 2]; // 每一项等于前两项之和
}
return arr[n - 1]; // 返回第 n 项
}
// 输出范围 [m, n] 内的所有 Fibonacci 数
void PrintFN(int m, int n) {
int a = 1, b = 1, c = a + b; // 初始化前三项
int printed = 0; // 标志位,记录是否输出了任何 Fibonacci 数
// 单独处理 m = 1 的情况
if (m <= 1 && n >= 1) {
printf("1 1"); // 前两项均为 1
printed = 1; // 设置标志位
}
// 遍历后续 Fibonacci 数
while (c <= n) {
if (c >= m) { // 如果当前项在范围内
if (printed) { // 如果之前已经打印了数字,打印空格分隔
printf(" ");
}
printf("%d", c); // 打印当前项
printed = 1; // 设置标志位
}
a = b; // 更新 a 为 b
b = c; // 更新 b 为当前项
c = a + b; // 计算下一项
}
if (!printed) { // 如果没有输出任何数字,打印提示
printf("No Fibonacci number");
}
printf("\n"); // 输出换行
}
// 测试程序
int main() {
int m, n, t;
// 输入范围 [m, n] 和第 t 项
scanf("%d %d %d", &m, &n, &t);
printf("fib(%d) = %d\n", t, fib(t)); // 输出第 t 项的 Fibonacci 数
PrintFN(m, n); // 输出范围内的所有 Fibonacci 数
return 0;
}
六.数组循环右移
#include <stdio.h>
#define MAXN 10
void ArrayShift( int a[], int n, int m );
int main()
{
int a[MAXN], n, m;
int i;
scanf("%d %d", &n, &m);
for ( i = 0; i < n; i++ ) scanf("%d", &a[i]);
ArrayShift(a, n, m);
for ( i = 0; i < n; i++ ) {
if (i != 0) printf(" ");
printf("%d", a[i]);
}
printf("\n");
return 0;
}
/* 你的代码将被嵌在这里 */
void ArrayShift( int a[], int n, int m ){
int newa[n]; // 创建一个临时数组来存储重新排列后的元素
m = m % n; // 对 m 取模,避免移动超过数组长度
// 遍历数组,将元素重新安排到新位置
for(int i = 0; i < n; i++){
if(n - 1 - i >= m){ // 如果当前元素的右侧剩余空间大于等于 m
newa[i + m] = a[i]; // 将当前元素移动到右侧 m 个位置
} else { // 当前元素不能完全移动到右侧
newa[m - n + i] = a[i]; // 将其循环移动到左侧剩余的位置
}
}
// 将临时数组的内容拷贝回原数组
for(int i = 0; i < n; i++){
a[i] = newa[i];
}
}
七.使用函数实现字符串部分复制
void strmcpy( char *t, int m, char *s ){
int count = 0; // 初始化计数器,用来跟踪拷贝的字符数
// 从 t[m-1] 开始遍历直到 t 中的字符 '\0' 结束
for(int i = m - 1; t[i] != '\0'; i++){
s[count++] = t[i]; // 将 t 中从 m-1 索引开始的字符逐个拷贝到 s 中
}
s[count] = '\0'; // 在 s 的末尾加上 null 字符 '\0',表示字符串结束
}
八.删除字符
#include <stdio.h>
#define MAXN 20
void delchar( char *str, char c );
void ReadString( char s[] ); /* 由裁判实现,略去不表 */
int main()
{
char str[MAXN], c;
scanf("%c\n", &c);
ReadString(str);
delchar(str, c);
printf("%s\n", str);
return 0;
}
/* 你的代码将被嵌在这里 */
void delchar( char *str, char c ) {
// 遍历整个字符串
for(int i = 0; str[i] != '\0'; i++) {
// 如果当前字符是待删除的字符
if(str[i] == c) {
// 从当前位置 i 开始,将后续字符往前移动一位
for(int j = i; str[j] != '\0'; j++) {
// 将 str[j+1] 的字符覆盖到 str[j]
str[j] = str[j + 1];
}
// 由于字符被删除,i 需要回退一位,继续检查当前位置的新字符
i--;
}
}
}
九.找最小的字符串
#include <stdio.h>
#include <string.h>
int main() {
int num; // 用于存储输入的字符串数量
char minStr[80]; // 用于存储当前最小的字符串
// 读取字符串数量
scanf("%d", &num);
// 读取第一个字符串,作为初始最小字符串
scanf("%s", minStr);
// 遍历剩余的字符串,逐一比较
for (int i = 0; i < num; i++) {
char str[80]; // 临时存储每次读取的字符串
scanf("%s", str); // 读取当前字符串
// 如果当前字符串小于 minStr(按字典序比较)
if (strcmp(minStr, str) > 0) {
strcpy(minStr, str); // 更新 minStr 为当前字符串
}
}
// 输出最小的字符串
printf("Min is: %s", minStr);
return 0;
}
十.字符串排序
#include<stdio.h>
#include<string.h>
int main() {
char str[5][80]; // 用于存储5个字符串的二维数组,每个字符串最长为79个字符
char temp[80]; // 用于在排序过程中临时交换字符串的变量
// 读取5个字符串输入
for (int i = 0; i < 5; i++) {
scanf("%s", str[i]); // 按顺序读取每个字符串
}
// 排序字符串(按字典序升序)
for (int i = 0; i < 5; i++) { // 遍历数组中的每个字符串
for (int j = i + 1; j < 5; j++) { // 比较当前字符串和之后的字符串
if (strcmp(str[i], str[j]) > 0) { // 如果 str[i] > str[j],则交换它们
strcpy(temp, str[j]); // 将 str[j] 存到 temp
strcpy(str[j], str[i]); // 将 str[i] 存到 str[j]
strcpy(str[i], temp); // 将 temp 存到 str[i]
}
}
}
// 输出排序后的字符串
printf("After sorted:\n");
for (int i = 0; i < 5; i++) {
printf("%s\n", str[i]); // 按行输出排序后的字符串
}
return 0;
}