C语言弯道超车必做好题集锦(编程题)

目录

前言:

1.计算日期到天数转换

2.尼科彻斯定理 

3.密码检查

4.图片整理

5.寻找数组的中心下标

6.字符个数统计

7.多数元素


扫描二维码关注公众号,回复: 16428264 查看本文章

前言:

编程想要学的好,刷题少不了,我们不仅要多刷题,还要刷好题!为此我开启了一个弯道超车必做好题锦集的系列,此为第一篇编程题篇,每篇大约5题左右。该系列会不定期更新,敬请期待!


1.计算日期到天数转换

描述

根据输入的日期,计算是这一年的第几天。

保证年份为4位数且日期合法。

进阶:时间复杂度: O(n) ,空间复杂度:O(1) 

输入描述:

输入一行,每行空格分割,分别是年,月,日

输出描述:

输出是这一年的第几天

#include<stdio.h>
int main()
{
    int arrmonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    int year, month, day;
    scanf("%d %d %d", &year, &month, &day);

    if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
        arrmonth[1]++;
    int i = 0;
    for (i = 0; i < month - 1; i++) 
    {
        day = day + arrmonth[i];
    }
    printf("%d", day);
    return 0;
}

思路:

1.闰年的判断方法

(1)能被4整除,但不能被100整除;

(2)能被400整除。

2. 每个月份的天数

一三五七八十腊 是31天, 二月,闰年 29天,平年28天, 其他月份是30天

3. 计算月份之前的n-1月的天数,加上本月的天数


2.尼科彻斯定理 

描述

验证尼科彻斯定理,即:任何一个整数m的立方都可以写成m个连续奇数之和。

例如:

1^3=1

2^3=3+5

3^3=7+9+11

4^3=13+15+17+19

输入一个正整数m(m≤100),将m的立方写成m个连续奇数之和的形式输出。

输入描述:

输入一个int整数

输出描述:

输出分解后的string

#include<stdio.h>
int main()
{
	int n = 0, i = 0; char str[1000];
	while (scanf("%d", &n) == 1)
	{
		int x = n + (n - 1) * (n - 1);
		sprintf(str, "%d", x);
		for (i = 0; i <n-1 ; i++)
		{
			x += 2;
			sprintf(str, "%s+%d", str, x);		
		}
		puts(str);
	}
	return 0;
}

解析:

数值大小是几,就会有几个奇数相加。

1^3=1                                

2^3=3+5

3^3=7+9+11

4^3=13+15+17+19

我们不难发现这是一个从1开始的奇数等差数列{1,3,5,7,9……}。

故我们只要知道了数值是几所对应的数,就可以知道相加的任意数,并且符合规律。

如:

1^3=1                                                          1- >1                          1+(1-1)^2

2^3=3+5                                                      2- >3                          2+(2-1)^2

3^3=7+9+11                                                3- >7                         3+(3-1)^2

4^3=13+15+17+19                                     4- >13                        4+(4-1)^2

……

……                                                                                               n+(n-1)^2

sprintf的用法如果不熟,可以看本博主的这篇文章。(在文件的顺序读写的第7个)

C语言文件操作_WHabcwu的博客-CSDN博客需求:我们想把信息记录下来,只有我们自己选择删除数据的时候,数据才不复存在。这就涉及到了数据持久化的问题,我们一般数据持久化的方法有,把数据存放在磁盘文件、存放到数据 库等方式。使用文件我们可以将数据直接存放在电脑的硬盘上,做到了数据的持久化。1.2。https://blog.csdn.net/WHabc2002/article/details/131755342


3.密码检查

描述

小明同学最近开发了一个网站,在用户注册账户的时候,需要设置账户的密码,为了加强账户的安全性,小明对密码强度有一定要求:

1. 密码只能由大写字母,小写字母,数字构成;

2. 密码不能以数字开头;

3. 密码中至少出现大写字母,小写字母和数字这三种字符类型中的两种;

4. 密码长度至少为8

现在小明受到了n个密码,他想请你写程序判断这些密码中哪些是合适的,哪些是不合法的。

输入描述:

输入一个数n,接下来有n(n≤100)行,每行一个字符串,表示一个密码,输入保证字符串中只出现大写字母,小写字母和数字,字符串长度不超过100。

输出描述:

输入n行,如果密码合法,输出YES,不合法输出NO

分析:

这道题只需要将字符串从头到尾的每种字符(大写字符,小写字符,数字,其他字符)分别统计出来后。然后逐个 判断是否符合条件即可。而条件的判断包含有:
长度不小于 8
不能以数字开头
只能包含字母和数字
大小写和字符必须具备两种以上

直接看代码:

#include<stdio.h>
#include<ctype.h>
#include<assert.h>
#include<string.h>
int f(char* arr)
{	    
	    assert(arr);
	    int i = 0;
		int sz = strlen(arr);
		if (sz < 8)
		{
			return 0;
		}
		if (arr[0] >= '0' && arr[0] <= '9')
		{
			return 0;
		}
		int* count = (int*)calloc(3, sizeof(int));
		for (i = 0; i < sz; i++)
		{
			
			if (arr[i] >= '0' && arr[i] <= '9')
			{
				count[0] = 1;
			}
			else if (islower(arr[i]))
			{
				count[1] = 1;
			}
			else if (isupper(arr[i]))
			{
				count[2] = 1;
			}
			else
			{
				free(count);
				return 0;
			}
		}
		if ((count[0] + count[1] + count[2] )>= 2)
		{
			free(count);
			return 1;
		}
		else
		{
			free(count);
			return 0;
		}

}
int main()
{
	char arr[101] = { 0 };
	int n=0;
	scanf("%d", &n);
	while (n)
	{
		scanf("%s", arr);
		n--;
		int x=f(arr);
		if (x == 1)
		{
			printf("YES\n");
		}
		else
		{
			printf("NO");
		}
	}
	
	return 0;
}

4.图片整理

描述

 输入描述:

 输出描述:

 

 代码:

#include<stdio.h>
#include<string.h>
int main()
{
	char arr[1000];
	gets(arr);
	int i = 0, j = 0;
	for (i = 0; i < strlen(arr) - 1; i++)
	{
		for (j = 0; j < strlen(arr) - 1 - i;j++)
		{
			if (arr[j] > arr[j + 1])
			{
				char t = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = t;
			}
		}
	}
	puts(arr);
	return 0;
}
【答案解析】:
这道题考察的其实就是字符排序,每个 ascii 字符在内存都有一个对应的 ascii 值,通过内存中数据的存储进行排序 就行。
冒泡排序:相邻数据之间进行比较交换,将较大或较小的数据向后推到数组末尾,然后开始下一轮次大数据的冒泡 过程。

5.寻找数组的中心下标

寻找数组的中心下标https://leetcode.cn/problems/find-pivot-index/

#include<stdio.h>
int pivotIndex(int* nums, int numsSize) {
	int total = 0;
	int i = 0;
	int sum = 0;
	for (i = 0; i < numsSize; i++)
	{
		total += nums[i];
	}
	for (i = 0; i < numsSize; i++)
	{
		if (2 * sum + nums[i] == total)
		{
			return i;
		}
		sum += nums[i];
	}
	return -1;
}

解析:

记数组arr的全部元素之和为 total,当遍历到第 i 个元素时,设其左侧元素之和为sum,

则其右侧元素之和为 total−sum-arr[i],左右侧元素相等即有arr[i]+sum*2=total.


6.字符个数统计

 思路:创建128大小的数组,标记出现过的字符,然后统计标记个数

#include<stdio.h>
#include<string.h>
int main()
{
	int arr[127] = { 0 };
	char str[500];
	gets(str);
	int i=0;
	int sz = strlen(str);
	int count = 0;
	for (i = 0; i < sz; i++)
	{
		if (arr[str[i]] == 0)
		{
			count++;
			arr[str[i]] = 1;
		}
	}
	
	printf("%d", count);
	return 0;
}

7.多数元素

多数元素https://leetcode.cn/problems/majority-element/

 方法1:数组排序法

思路:

如果将数组 nums 中的所有元素按照单调递增或单调递减的顺序排序,那么下标为 n/2
的元素(下标从 0 开始)一定是众数。

int majorityElement(int* nums, int numsSize) {
	int i = 0, j = 0;
	for (i = 0; i < numsSize-1; i++)
	{
		for (j = 0; j < numsSize - 1; j++)
		{
			if (nums[j] < nums[j + 1])
			{
				int t = nums[j];
				nums[j] = nums[j + 1];
				nums[j + 1] = t;
			}
		}
	}
	return nums[numsSize / 2];
}

因为冒泡排序的时间复杂度为O(n^2)

方法2:摩尔投票法

int majorityElement(int* nums, int numsSize){
int count = 1;
int tmp = nums[0];
for (int i = 1; i < numsSize; i++) {
if (tmp == nums[i]){//与保存的字符相同则计数+1
count++;
} else {//与保存的字符不同则计数-1
count--;
//计数为0表示有可能保存的字符不是最多的字符,换下一个
if (count == 0) tmp = nums[i + 1];
}
}
return tmp;
}
【答案解析】:
一个数组中有一个数字出现次数大于 n/2 ,从第 0 个字符开始,假设它就是最多的那个数字,遇到相同的数字则 计数 +1 , 遇到不同的则计数 -1 ,其实就是互相消耗,等到计数为 0 的时候,表示本次互拼完毕,从下一个字符重 新开始互拼,但是归根结底出现次数大于 n/2 的这个数字数量更多,因此也是最后保留的字符。
示例:
"23335" 首先从字符 2 开始计数 1 ,遇到 3 ,不同则 -1 ,互拼消耗 重新从剩下的 "335" 开始的过程,这时 候保存的字符为 3 ,遇到 3 则计数 +1 , 遇到 5 则计数 -1 ,在计数不为 0 时,走到末尾保存的字符就是个数超过 n/2 的字符


以上为我个人的小分享,如有问题,欢迎讨论!!! 

都看到这了,不如关注一下,给个免费的赞 

 

猜你喜欢

转载自blog.csdn.net/WHabc2002/article/details/131967336
今日推荐