【C语言学习者必会的题目集锦1】巩固基础,稳步提高

简介: 【C语言学习者必会的题目集锦1】巩固基础,稳步提高

1.打印空格和星号的规律

点我做题:BC65 箭形图案


5c1c0411803f4430a9e57da82b47cd04.png

#include<stdio.h>
int main()
{
    int n=0;
    while(~scanf("%d",&n))
    {
        //上半部分n+1行
        for(int i=1;i<=n+1;i++)
        {
            //空格
            for(int j=1;j<=n+1-i;j++)
            {
                printf("  ");
            }
            //星号
            for(int j=1;j<=i;j++)
            {
                printf("*");
            }
            printf("\n");
        }
        //下半部分n行
        for(int i=1;i<=n;i++)
        {
            //空格
            for(int j=1;j<=i;j++)
            {
                printf("  ");
            }
            //星号
            for(int j=1;j<=n+1-i;j++)
            {
                printf("*");
            }
            printf("\n");
        }
    }
    return 0;
}

这题的启示:


可以把两个空格作为一次性输出,只要for循环里的判断条件你好写,怎么样都行!!


学习到牛客网:原来可以通过鼠标可以查看空格有多少个!!!


我的做题感悟:


分为上下两部分,每行就是空格和星号组成也是老生常谈了

形成自己的风格:for(int i=1;i<=N;i++)这样的题从1开始,然后<=某一个数

找规律,空格和星号的循环判断条件:越来越多,用i,然后加减某一个数,越来越少,用n-i,然后加减某一个数,这个某一个数可以通过第一个外层循环的i带入来知晓。


2.别样的多组输入

点我做题:公务员面试

#include<stdio.h>
int main()
{
    int score=0;//分数(整数)
    int max=0;
    int min=100;//最小值先给最大的
    int count=0;//计数器,7个一组
    int sum=0;//7个整数的和
    while(scanf("%d",&score)!=EOF)//一次输入一个
    {
        if(max<score)  max=score;
        if(min>score)  min=score;
        sum+=score;
        count++;
        if(count==7)//7个为一组,够了7个重新初始化
        {
            printf("%.2lf\n",(sum-min-max)/5.0);//格式输出:换行
            max=0;
            min=100;
            sum=0;
            count=0;
        }
    }
    return 0;
}

这题的提示:

对于多组输入,且是一组输入多个数据,可能大多数人想到的做法是:对于每一组数据一次性输完

f5477adab3cb4895bc8e489e97d31270.png

但是这样即不美观,当数据多了就...

3.左旋字符串的多种解法

题目:

实现一个函数,可以左旋字符串中的k个字符。

例如:

ABCD左旋一个字符得到BCDA

ABCD左旋两个字符得到CDAB

方法1:保存前移

f4beb0a66bc74bd4bb681b2119c760f7.png

#include<string.h>
void LeftRound(char* str, int k)
{
  int len = strlen(str);
  k = k%len;
  for (int i = 0; i < k; i++)
  {
    char temp = str[0];
    for (int i = 1; i <= len - 1; i++)
    {
      str[i - 1] = str[i];
        }
    str[len - 1] = temp;
  }
}
int main()
{
  char str[20] = "hello world";
  int k = 0;
  scanf("%d", &k);
  LeftRound(str, k);
  printf("%s\n", str);
  return 0;
}

45bbf3892db4453c8a79583df7f14baf.png

启发:

k=k%len;提高效率

方法2:临时数组

cfbb5ec324f745a7aff5d19494934876.png

#include<stdlib.h>
void LeftRound(char* str, int k)
{
  int len = strlen(str);
  k = k % len;
  char* temp = (char*)malloc(sizeof(len + 1));
  if (temp == NULL)
  {
    perror(temp);
    return -1;
  }
  strcpy(temp, str + k);
  strncat(temp, str, k);
  strcpy(str, temp);
}
int main()
{
  char str[20] = "hello world";
  int k = 0;
  scanf("%d", &k);
  LeftRound(str, k);
  printf("%s\n", str);
  return 0;
}

方法3: 三次反转

2b2bb0298cc04ab8a6a809ca5d328916.png

void Rotate(char* str, int left, int right)
{
  while (left < right)
  {
    char temp = str[left];
    str[left] = str[right];
    str[right] = temp;
    left++;
    right--;
  }
}
void LeftRound(char* str, int k)
{
  int len = strlen(str);
  k = k % len;
  Rotate(str, 0, k - 1);
  Rotate(str, k, len - 1);
  Rotate(str, 0, len - 1);
}
int main()
{
  char str[20] = "hello world";
  int k = 0;
  scanf("%d", &k);
  LeftRound(str, k);
  printf("%s\n", str);
  return 0;
}

rotate:旋转

reverse:反转

4.数组中出现次数超过一半的数字

点我做题:NC73 数组中出现次数超过一半的数字

方法1:哈希表

本题涉及到<数组元素,出现次数>之间的对应映射关系,这种方法应该不难想到,把数组元素出现的次数存到一个标记数组map里,然后遍历一遍map标记数组,找到次数>half的元素就行!

int MoreThanHalfNum_Solution(int* numbers, int numbersLen ) {
    // write code here
    int map[10000]={0};
    int half=numbersLen/2;
    for(int i=0;i<numbersLen;i++)
    {
        map[numbers[i]]++;
    }
    for(int i=0;i<numbersLen;i++)
    {
        if(map[numbers[i]]>half)
        {
           return numbers[i];
        }
    }
    return 0;
}

时间复杂度:O(n)

空间复杂度:O(1)

方法2:排序中值法

由于题目给定输入的数组"一定非空",也就是numbersLen>=1,还给定"且保证有解",那么数组中一定存在一个出现次数超过一半的数组元素。


那么如果我们给数组先进行排序,然后取排完序的数组的中间元素,那一定就是目标值!


也就是快速排序+返回numbers[mid]的代码,简单!不写!


有人可能又要问数组元素取numbers[mid]的时候是否要分奇偶,不需要!(因为蓝色标注)


时间复杂度:O(nLogN)


空间复杂度:O(1)

方法3:消除异值法

只要我们把数组元素不同的两个值给消除掉,因为一定存在一个次数超过数组一半的元素,

所以最后留下来的那个数组值一定是目标值!

int MoreThanHalfNum_Solution(int* numbers, int numbersLen ) {
    if(numbers==NULL) return -1;
    int time=1;
    int target=numbers[0];
    for(int i=1;i<numbersLen;i++)
    {
        if(time==0)
        {
            target=numbers[i];
            time=1;
            continue;
        }
        if(target==numbers[i])
        {
            time++;
        }
        else
        {
            time--;
        }
    }
    return target;
    return 0;
}
目录
相关文章
|
6月前
|
存储 C语言
C语言学习记录——动态内存函数介绍(malloc、free、calloc、realloc)
C语言学习记录——动态内存函数介绍(malloc、free、calloc、realloc)
444 1
|
2月前
|
程序员 C语言
【C语言】LeetCode(力扣)上经典题目
【C语言】LeetCode(力扣)上经典题目
|
2月前
|
C语言
教你快速理解学习C语言的循环与分支
教你快速理解学习C语言的循环与分支
17 0
|
4月前
|
存储 编译器 C语言
【C语言】指针练习题目
【C语言】指针练习题目
|
4月前
|
编译器 C语言
C语言函数的学习
掌握函数的使用是学习C语言的关键一环,理解和应用这些基本的函数概念将使你能够更有效地利用C语言的强大功能。
25 0
|
6月前
|
存储 程序员 Go
|
6月前
|
存储 编译器 C语言
c语言学习历程【1】
c语言学习历程【1】
77 1
|
6月前
|
C语言
C语言学习记录——通讯录(静态内存)
C语言学习记录——通讯录(静态内存)
33 2
|
6月前
|
测试技术 C语言
数据结构学习记录——树习题—Tree Traversals Again(题目描述、输入输出示例、解题思路、解题方法C语言、解析)
数据结构学习记录——树习题—Tree Traversals Again(题目描述、输入输出示例、解题思路、解题方法C语言、解析)
48 1
|
6月前
|
C语言
C语言学习记录——动态内存开辟常见的错误
C语言学习记录——动态内存开辟常见的错误
37 1