目录
前言:
1.计算日期到天数转换
2.尼科彻斯定理
3.密码检查
4.图片整理
5.寻找数组的中心下标
6.字符个数统计
7.多数元素
前言:
编程想要学的好,刷题少不了,我们不仅要多刷题,还要刷好题!为此我开启了一个弯道超车必做好题锦集的系列,此为第一篇编程题篇,每篇大约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 的字符
以上为我个人的小分享,如有问题,欢迎讨论!!!
都看到这了,不如关注一下,给个免费的赞