W...Y的主頁?😊
代碼倉庫分享💕
今天繼續分享C語言必會的題目,上一篇文章主要是一些選擇題,而今天我們主要內容為編程題的推薦與講解
準備好迎接下面的題了嗎?開始發車了!!!
輸入數字 n ,按順序打印出從 1 到最大的 n 位十進制數。比如輸入 3 ,則打印出 1、2、3 一直到最大的 3 位 數 999 。
用返回一個整數列表來代替打印
n 為正整數 OJ鏈接
OJ鏈接【牛客網題號: JZ17 打印從1到最大的n位數】
示例: 輸入:1 返回值:[1,2,3,4,5,6,7,8,9]
首先我們要對題目進行分析,這里可以理解為n位數中最大的數字,從1開始。實際上是用一個數組來打印這些數字。那我們就得求出一共有多少數字:10^n-1個。比如:1位數10^1 - 1 2位數: 10^2 - 1 3位數: 10^3 - 1。
n在不同情況下不同,如果創建一個能兼容所有的數組會很浪費內存,所以我們使用malloc動態內存開辟解決問題。
注意:是數組下標從0開始,而數值從1開始
int* printNumbers(int n, int* returnSize ) { *returnSize = pow(10, n) - 1; //確定最大的數字 int *arr = (int *)malloc(sizeof(int)*(*returnSize));//申請足夠大小的空間 for (int i = 0; i < *returnSize; i++) { arr[i] = i+1;//下標從0開始,而數值從1開始 } return arr; }
根據輸入的日期,計算是這一年的第幾天。輸入保證年份為4位數且日期合法。
輸入描述:輸入一行,每行空格分割,分別是年,月,日。
輸出描述:輸出是這一年的第幾天
OJ鏈接【牛客網題號: HJ73 計算日期到天數轉換】?
這道題簡單解法其實將每個月的天數枚舉出來,然后根據當前月份向前累加滿月的天數,然后再加上當前月所在的 天數。最終考慮平閏年的 2 月份區別是否增加一天。
注意:當二月份沒過完時,閏年與平年的判斷就沒有用,不需要+1或不加,這里得用if進行判斷。例如:2000年2月1日 ,雖然是閏年,但是 2月 都沒走完那是不能加上閏年多出的一天的。
#include <stdio.h>int is_leap_year(int year) { if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {return 1; }return 0; } int main() {int a, b, c;int count = 0;int mouth[12] = {31,28,31,30,31,30,31,31,30,31,30,31};while (scanf("%d %d %d", &a, &b, &c) != EOF) { // 注意 while 處理多個 casefor(int i = 0; i < b-1; i++){count += mouth[i]; }count += c;if(b>2)count += is_leap_year(a);printf("%d\n", count);}return 0; }
判斷閏年方法:能被4整除不能被100整除或者能被400整除。
驗證尼科徹斯定理,即:任何一個整數 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
OJ鏈接【牛客網題號: HJ76 尼科徹斯定理】
示例: 輸入:6 輸出:31+33+35+37+39+41
看到此題,我們必須在里面找到規律,這樣才能快速解題。
首先我們可以看出尼科徹斯定理n是幾,后面組成的數就有幾個并且全部都是連續奇數。
這時我們就可以遍歷求和來得到需要的內容,但是這樣的時間復雜度太高,為了優化代碼我們繼續找其中規律。
能夠找到第 n 個數據立方的起始奇數,從這個起始奇數開始,組成連續的n個奇數 項之和的表達式即可。比如: 3^3 的起始奇數是 7 , 則 {7, 9, 11} 3個奇數求和表達式 7 + 9 + 11 。而起始奇數有個規則: m^3 的起始奇數值等于 m * (m - 1) + 1。
能找到起始奇數就非常簡單了,只需要再加n-1個奇數即可得到結果。
#include <stdio.h> int main() {int m = 0;while(scanf("%d", &m) != EOF){int n = m*(m-1)+1;char arr[1000] = {0};sprintf(arr, "%d", n);for(int i = 1 ; i < m; i++){sprintf(arr, "%s+%d", arr, n +=2);}printf("%s", arr);}return 0; }
打印時得輸出內容的加和,所以我們將其放入字符數組中進行打印。
sprintf:將格式化數據轉換成字符串,用法與printf大差不差,只是在參數中多一個轉入指針(接收想轉入的地址)?。
首先輸入要輸入的整數個數 n ,然后輸入 n 個整數。輸出為 n 個整數中負數的個數,和所有正整數的平均值, 結果保留一位小數。
注意: 0 即不是正整數,也不是負數,不計入計算;
本題有多組輸入用例。
輸入描述:首先輸入一個正整數 n ,然后輸入 n 個整數。
輸出描述:輸出負數的個數,和所有正整數的平均值。
OJ鏈接【牛客網題號: HJ97 記負均正】
示例: 輸入: 5
1 2 3 4 5
10
1 2 3 4 5 6 7 8 9 0
輸出: 0 3.0? ? ? ? 0 5.0
這道題我們最常用的思路使用數組進行操作,但其實我們直接使用scanf捕捉數據即可,統計負數個數,以及正數格式,并且在統計正數個數的過程中求取正數總 和,最后計算得出平均數即可。需要注意的是所有數字中0是不統計在內的。
int main() {int n;while(~scanf("%d", &n)) {int count1 = 0, count2 = 0, tmp;float sum = 0;for (int i = 0; i < n; i++) {scanf("%d", &tmp);if (tmp < 0) {count1++; //統計負數個數}else if (tmp > 0) {sum += tmp; //正數求和count2++; //統計大于0的正數個數,這樣是因為題目說明0不算在內}}printf("%d %.1lf\n", count1, sum / count2);}return 0; }
數字總和一定要使用浮點數進行,否則得不到浮點數結果。整數與整數相除得不到浮點數!
小明同學最近開發了一個網站,在用戶注冊賬戶的時候,需要設置賬戶的密碼,為了加強賬戶的安全性,小明對密碼強度有一定要求:
1.?密碼只能由大寫字母,小寫字母,數字構成;
2.?密碼不能以數字開頭;
3.?密碼中至少出現大寫字母,小寫字母和數字這三種字符類型中的兩種;
4.?密碼長度至少為8
現在小明受到了n個密碼,他想請你寫程序判斷這些密碼中哪些是合適的,哪些是不合法的。
輸入描述:輸入一個數n,接下來有n(n≤100)行,每行一個字符串,表示一個密碼,輸入保證字符串中只出現大寫字母,小寫字母和數字,字符串長度不超過100。
輸出描述:輸入n行,如果密碼合法,輸出YES,不合法輸出NO
示例: 輸入:1
CdKfIfsiBgohWsydFYlMVRrGUpMALbmygeXdNpTmWkfyiZIKPtiflcgppuR
輸出:YES
OJ鏈接【牛客網題號: OR141 密碼檢查】
這道題并不難,但是要求的條件非差多,當我們使用if else語句時,直接將密碼遍歷一遍進行層層嵌套也可以,但是可讀性非常差。所以我們可以直接遍歷一遍統計出大小寫以及數字的字符個數,通過這些個數進行判斷更加方便。
#include <stdio.h>int main() {int n; while(scanf("%d", &n)!=EOF) {for (int i = 0; i < n; i++) {char password[101] = {0};int upper = 0, lower = 0, digit = 0, other = 0;scanf("%s", password);//捕捉輸入的密碼if (strlen(password) < 8) {//密碼長度小于8printf("NO\n");continue;}if (password[0] >= '0' && password[0] <= '9') {//密碼以數字開頭printf("NO\n");continue;}char *ptr = password;while(*ptr != '\0') { //統計各種字符個數if (*ptr >= 'a' && *ptr <= 'z') lower++;else if (*ptr >= 'A' && *ptr <= 'Z') upper++;else if (*ptr >= '0' && *ptr <= '9') digit++;else other++;ptr++;}if (other > 0) { // 有其他字符(注意:密碼只能由數字和字母組成)printf("NO\n");continue;} //大寫,小寫,數字,必須具有兩種以上,而比較運算真則1,假則0if ((upper>0) + (lower>0) + (digit>0) < 2) { // 密碼只有一種字符printf("NO\n");continue;}printf("YES\n");}}return 0; }
給你一個整數數組 nums ,其中總是存在 唯一的 一個最大整數 。請你找出數組中的最大元素并檢查它是否 至 少是數組中每個其他數字的兩倍 。如果是,則返回 最大元素的下標 ,否則返回 -1 。
OJ鏈接【 leetcode 題號:747. 至少是其他數字兩倍的最大數】?
示例: 輸入:nums = [3,6,1,0] 輸出:1
解釋:6 是最大的整數,對于數組中的其他整數,6 大于數組中其他元素的兩倍。6 的下標是 1 ,所以返回 1 。
輸入:nums = [1,2,3,4] 輸出:-1
解釋:4 沒有超過 3 的兩倍大,所以返回 -1 。
輸入:nums = [1] 輸出:0
解釋:因為不存在其他數字,所以認為現有數字 1 至少是其他數字的兩倍。
方法一:暴力破解,雙重循環遍歷數組,對每個元素判斷是否是其他元素的兩倍。或者先遍歷一遍找出最大值,然后遍歷一 遍判斷是否是其他數字二倍。
但是這個方法時間復雜度太高,那喲沒有什么更簡潔的代碼嗎?
一次遍歷找出最大的數字和次大的數字,判斷最大的數字是否是次大數字2倍即可。
int dominantIndex(int* nums, int numsSize){int max = 0;int a = 0;int lmax = 0;for(int i = 0 ; i < numsSize; i++){if(nums[i]>max){max = nums[i];a = i;}}for(int i = 0 ; i < numsSize; i++){if(i != a)if(nums[i]>lmax)lmax = nums[i];}if(max >= 2 * lmax)return a;elsereturn -1; }
時間復雜度為O(n).
給定兩個數組,編寫一個函數來計算它們的交集。
OJ鏈接【 leetcode 題號:349. 兩個數組的交集】?
示例: 輸入:nums1 = [1,2,2,1], nums2 = [2,2] 輸出:[2]
輸入:nums1 = [4,9,5], nums2 = [9,4,9,8,4] 輸出:[9,4]
1 <= nums1.length, nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 1000
?暴力破解即可,將 nums1 數組中的每一個數字,判斷是否存在于 nums2 數組中,通過這種方式找出交集數據,找出之后判斷這個數組是否已經在返回數組中存在,不存在則添加到返回數組中即可。
int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){static int arr[1000];*returnSize = 0;int i, j, k;for (i = 0; i < nums1Size; i++) {for (j = 0; j < nums2Size; j++) {if (nums2[j] == nums1[i]) break;//判斷nums1[i] 是否在nums2數組中}if (j == nums2Size) {// nums1中i位置的數據在nums2數組中不存在,則非交集數據continue;}//只有在另一個數組中存在的數據才能走下來,判斷是否已經被添加到返回數組中for (j = 0; j < *returnSize; j++) {if (nums1[i] == arr[j]) break;//判斷nums1[i] 是否在 arr 這個返回數組中}if (j == *returnSize) {//不在返回數組中,則添加到返回數組中arr[*returnSize] = nums1[i];*returnSize += 1;}}return arr; }
給你一個整數數組 nums ,請計算數組的 中心下標 。
數組 中心下標 是數組的一個下標,其左側所有元素相加的和等于右側所有元素相加的和。 如果中心下標位于數組最左端,那么左側數之和視為 0 ,因為在下標的左側不存在元素。這一點對于中心下標位于 數組最右端同樣適用。?
如果數組有多個中心下標,應該返回 最靠近左邊 的那一個。如果數組不存在中心下標,返回 -1 。
OJ鏈接【 leetcode 題號:724. 尋找數組的中心下標】
示例: 輸入:nums = [1, 7, 3, 6, 5, 6]
輸出:3 解釋: 中心下標是 3 。 左側數之和 sum = nums[0] + nums[1] + nums[2] = 1 + 7 + 3 = 11 , 右側數之和 sum = nums[4] + nums[5] = 5 + 6 = 11 ,二者相等。
輸入:nums = [2, 1, -1] 輸出:0? 解釋: 中心下標是 0 。 左側數之和 sum = 0 ,(下標 0 左側不存在元素), 右側數之和 sum = nums[1] + nums[2] = 1 + -1 = 0 。
解題思路:從數組的0下標處開始向后逐下標統計,計算當前下標左邊之和,和右邊之和,進行判斷,相等則為中心下標,如 果數組循環結束都沒有找到中心下標,則返回-1,表示沒有中心下標。
int pivotIndex(int* nums, int numsSize) {int i, j;for (i = 0; i < numsSize; i++){int sum_left = 0, sum_right = 0;for (j = 0; j < numsSize; j++){if (i > j){sum_left += nums[j];}else if (i < j){sum_right += nums[j];}}if (sum_left == sum_right){return i;}}return -1; }
Lily上課時使用字母數字圖片教小朋友們學習英語單詞,每次都需要把這些圖片按照大小(ASCII碼值從小到 大)排列收好。請大家給Lily幫忙,通過C語言解決。
輸入描述:Lily使用的圖片包括 "A" 到 "Z" 、 "a" 到 "z" 、 "0" 到 "9" 。輸入字母或數字個數不超過 1024 。
輸出描述:Lily的所有圖片按照從小到大的順序輸出
OJ鏈接【牛客網題號: HJ34 圖片整理】
示例: 輸入:Ihave1nose2hands10fingers
???????????輸出:0112Iaadeeefghhinnnorsssv
這道題就是考察我們如何排序,,每個 ascii 字符在內存都有一個對應的 ascii 值,通過內存中數據的存儲進行排序就行。
什么排序方法都行:多種排序方法?有不同排序方法供參考,下面我們使用qsort函數進行排序做題。
#include <stdio.h> #include<string.h> #include<stdlib.h>int compar(const void* p1, const void* p2) {return *(char*)p1 - *(char*)p2; } int main() {char arr[1000];gets(arr);int sz = strlen(arr);qsort(arr, sz, sizeof(char), compar);printf("%s\n", arr);return 0; }
使用qosrt函數非常簡潔方便,不知道如何使用qsort函數,博主之前的博客中有解說:qsort函數使用及模擬
?以上是本次推薦的所以內容,感謝大家觀看,請多多支持博主。你們的支持是我最大的動力!!!