第11周編程題在線測試
NOTE:
- 指針變量:保存地址型數據,必須初始化才能使用,否則會指向不確定的存儲單元。
- &a[i] 等於 *(a + i)
- ‘^’ 異或操作:0和任何數異或等於本身;1和任何數異或取相反數;數自己和自己異或等於0。
- 二維數組a[N][N]中,a代表二維數組的首地址,第0行的地址,行地址,a + i代表第i行的首地址,並非表示&a[0][i]。
- int (* p) [3] 定義的是行指針,基類型爲“int[3]型”,意思是指向一個含有3個整型元素的數組的指針 a[i][j] 等於 *( *(a + i) + j ) ,與此易混淆的是 int * p[3] 這個定義的是一個指針數組,同理,對於函數定義 int * p( ) 返回的是int * 型,而int ( *p)( )返回值爲整型,其中 指針變量p指向返回值爲整型的函數。、
- int *p = *a; //a[0] 定義的是列指針;a[i][j] 等於 *( p + i * n + j)。
- 關於main函數中的命令行參數:我們知道C99標準中對於main函數的正確寫法只有兩種,吐槽一下老譚酸菜程序設計面=-=,言歸正傳,請看下面:
int main(void) //不帶參數的main函數
{
//TODO
return 0;
}
int main(int argc, char* argv[]) //帶參數的main函數
{
//TODO
return 0;
}
從第二個帶參數的main函數中可以看到,第一個參數爲int型的變量,大小爲命令行參數的個數,第二個參數爲指向字符串的指針數組,其中argv[0]爲自身.c文件編譯後的可執行文件.exe的路徑,其餘的需要自己定義,比如在CodeBlocks下可以在Project–>Set programs’ arguments彈出的對話框中設置。
1. 山地訓練
題目內容:
爲了能在下一次跑步比賽中有好的發揮,小白在一條山路上開始了她的跑步訓練。她希望能在每次訓練中跑得儘可能遠,不過她也知道農場中的一條規定:女孩子獨自進山的時間不得超過M秒(1 <= M <= 10,000,000)。假設整條山路劃分成T個長度相同的路段(1 <= T <= 100,000),並且小白用si表示第i個路段的路況,用u、f、d這3個字母分別表示第i個路段是上坡、平地、下坡。小白跑完一段上坡路的耗時是U秒(1 <= U <= 100),跑完一段平地的耗時是F秒(1 <= F <= 100),跑完一段下坡路的耗時是D秒(1 <= D <= 100)。注意,沿山路原路返回時,原本是上坡的路段變成了下坡路段,原本是下坡的路段變成了上坡路段。小白想知道,在能按時返回農場的前提下,她最多能在這條山路上跑多少個路段。請你編程幫助她計算。
函數原型: long Fun(long M, long T, long U, long F, long D, char str[]);
函數功能: 計算在限時M秒內T個路段的情況下,最多往返可跑的路段數。 參數:M,T,U,F,D分別代表限時、路段數,以及上坡、平地、下坡的耗時,數組str保存整條山路的路段狀況,返回值:最多可跑的路段數。
#include<stdio.h>
#include<string.h>
long Fun(long M, long T, long U, long F, long D, char str[]);
int main(void)
{
long M, T, U, F, D, num;
char str[100000];
printf( "Input M,T,U,F,D:");
scanf("%ld%ld%ld%ld%ld",&M,&T,&U,&F,&D);
printf("Input conditions of road:");
scanf("%s",str);
num = Fun(M,T,U,F,D,str);
printf("num=%ld\n",num);
return 0;
}
long Fun(long M, long T, long U, long F, long D, char str[])
{
long i;
long sum = 0;
for(i = 0; i < T; i++)
{
if(str[i] == 'f')
sum += 2*F;
else
sum += U + D;
if(sum > M)
return i;
}
return T - 1; //我覺得應該是 8, 怎麼會是7呢,這麼多時間肯定能跑完啊,有問題
}
2. 奇偶數分離
題目內容:
輸入n個整數(n從鍵盤輸入,假設n的值不超過100),按奇偶數分成兩組並輸出。輸出兩行,第一行爲所有奇數,第二行爲所有偶數,保持數據的相對順序與輸入順序相同。
函數原型: void Seperate(int a[], int n); //數組a[]存放用戶輸入的n個整數
解題思路: 用兩個循環分別輸出奇數和偶數,在輸出第一個數時用"%d"格式字符,在輸出其餘數時用",%d"格式字符,用標誌變量記錄和判斷是否是第一個奇數或偶數。
#include<stdio.h>
#define N 100
void Seperate(int a[], int n);
int main(void)
{
int n;
int a[N] = {0};
printf("Input n:");
scanf("%d", &n);
printf("Input numbers:");
for(int i = 0; i < n; i++)
scanf("%d",&a[i]);
Seperate(a, n);
return 0;
}
void Seperate(int a[], int n)
{
int i, count = 0;
for(i = 0; i < n; i++)
{
if(a[i]%2 == 1)
{
if(count == 0)
printf("%d",a[i]);
else
printf(",%d",a[i]);
count++;
}
}
count = 0;
printf("\n");
for(i = 0; i < n; i++)
{
if(a[i]%2 == 0)
{
if(count == 0)
printf("%d",a[i]);
else
printf(",%d",a[i]);
count++;
}
}
}
3. 子串判斷
題目內容:
從鍵盤輸入兩個長度小於80的字符串A和B,且A的長度大於B的長度,編程判斷B是不是A的子串,如果是,則輸出”Yes”,否則輸出”No”。這裏所謂的該串的子串是指字符串中任意多個連續的字符組成的子序列。
函數原型: int IsSubString(char a[], char b[]);
函數功能: 判斷b是否是a的子串,是則返回1,否則返回0
#include<stdio.h>
#include<string.h>
#define N 80
int IsSubString(char a[], char b[]);
int main(void)
{
char a[N], b[N];
printf("Input the first string:");
gets(a);
printf("Input the second string:");
gets(b);
if(IsSubString(a,b))
printf("Yes\n");
else
printf("No\n");
return 0;
}
int IsSubString(char a[], char b[])
{
int i, j;
int alen = strlen(a);
int blen = strlen(b);
for(i = 0; i < alen; i++)
{
int pos = 0;
for(j = 0; j < blen; j++)
{
if(a[i + pos] == b[j])
pos++;
}
if(pos == blen)
return 1;
}
return 0;
}
4. 星期查找
題目內容:
任意輸入英文的星期幾,通過查找如圖所示的星期表,輸出其對應的數字,若查到表尾,仍未找到,則輸出錯誤提示信息。
#include<stdio.h>
#include<string.h>
#define N 20
int main(void)
{
char weekDay[7][N] = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
char str[N];
char (*p)[N] = weekDay;
printf("Please enter a string:\n");
gets(str);
for(int i = 0; i < 7; i++)
{
if(strcmp(str,p + i) == 0)
{
printf("%s is %d\n",str,i);
return 0;
}
}
printf("Not found!\n");
return 0;
}
第11周練兵區編程題
1. 找出按字典順序排在最前面的國名
題目內容:
輸入5個國名,編程找出並輸出按字典順序排在最前面的國名。
#include<stdio.h>
#include<string.h>
#define N 20
int main(void)
{
char country[5][N];
char *min = country[0];
int i;
printf("Input five countries' names:\n");
for(i = 0; i < 5; i++)
gets(country[i]);
for(i = 0; i < 5; i++)
{
printf("%d\n",strcmp(min,country[i]));
if(strcmp(min,country[i]) > 0)
strncpy(min,country[i],sizeof(country[i]));
}
printf("The minimum is:%s\n",min);
return 0;
}
3. 月份表示
題目內容:
用指針數組保存表示每個月份的英文單詞以及“Illegal month”的首地址,然後編程實現:從鍵盤任意輸入一個數字表示月份值n,程序輸出該月份的英文表示,若n不在1~12之間,則輸出“Illegal month”。
#include<stdio.h>
#include<string.h>
#define N 15
int main(void)
{
char month[13][N] = {"Illegal month", "January", "February", "March", "April", "May",
"June", "July", "August", "September", "October", "November", "December"};
int num;
printf("Input month number:\n");
scanf("%d",&num);
if(num > 12 ||num < 1)
printf("%s\n",month[0]);
else
printf("month %d is %s\n", num, month[num]);
return 0;
}
4. 程序改錯——1
題目內容:
從鍵盤任意輸入m個學生n門課程的成績,然後計算每個學生各門課的總分sum和平均分aver。下面程序存在極爲隱蔽的錯誤,請分析錯誤的原因,並修改程序,同時按照給出的程序運行示例檢查修改後的程序。
#include <stdio.h>
#define STUD 30 //最多可能的學生人數
#define COURSE 5 //最多可能的考試科目數
void Total(int *score, int sum[], float aver[], int m, int n);
void Print(int *score, int sum[], float aver[], int m, int n);
int main(void)
{
int i, j, m, n, score[STUD][COURSE], sum[STUD];
float aver[STUD];
printf("Enter the total number of students and courses:\n");
scanf("%d%d",&m,&n);
printf("Enter score:\n");
for (i=0; i<m; i++)
{
for (j=0; j<n; j++)
{
scanf("%d", &score[i][j]);
}
}
Total(*score, sum, aver, m, n);
Print(*score, sum, aver, m, n);
return 0;
}
void Total(int *score, int sum[], float aver[], int m, int n)
{
int i, j;
for (i=0; i<m; i++)
{
sum[i] = 0;
for (j=0; j<n; j++)
{
sum[i] = sum[i] + *(score + i * COURSE + j);
}
aver[i] = (float) sum[i] / n;
}
}
void Print(int *score, int sum[], float aver[], int m, int n)
{
int i, j;
printf("Result:\n");
for (i=0; i<m; i++)
{
for (j=0; j<n; j++)
{
printf("%4d\t", *(score + i * COURSE + j));
}
printf("%5d\t%6.1f\n", sum[i], aver[i]);
}
}
5. 程序改錯——2
題目內容:
下面主函數調用函數SortString()按奧運會參賽國國名在字典中的順序對其入場次序進行排序,目前程序存在錯誤,請修改正確,並按照給出的程序運行示例檢查修改後的程序。
#include <stdio.h>
#include <string.h>
#define M 150 /* 最多的字符串個數 */
#define N 10 /* 字符串最大長度 */
void SortString(char *ptr[], int n);
int main()
{
int i, n;
char str[M][N];
char *pStr[M];
for(int i = 0; i < M; i++)
pStr[i] = str[i];
printf("How many countries?\n");
scanf("%d",&n);
getchar(); /* 讀走輸入緩衝區中的回車符 */
printf("Input their names:\n");
for (i=0; i<n; i++)
{
gets(pStr[i]); /* 輸入n個字符串 */
}
SortString(pStr, n); /* 字符串按字典順序排序 */
printf("Sorted results:\n");
for (i=0; i<n; i++)
{
puts(pStr[i]); /* 輸出排序後的n個字符串 */
}
return 0;
}
void SortString(char *ptr[], int n)
{
int i, j;
char *temp = NULL;
for (i=0; i<n-1; i++)
{
for (j=i+1; j<n; j++)
{
if (strcmp(ptr[j], ptr[i]) < 0)
{
temp = ptr[i];
ptr[i] = ptr[j];
ptr[j] = temp;
}
}
}
}
6. 找數組最值
題目內容:
按如下函數原型編程從鍵盤輸入一個m行n列的二維數組,然後計算數組中元素的最大值及其所在的行列下標值。其中,m和n的值由用戶鍵盤輸入。已知m和n的值都不超過10。
void InputArray(int *p, int m, int n);
int FindMax(int *p, int m, int n, int *pRow, int *pCol);
#include<stdio.h>
#define N 10
void InputArray(int *p, int m, int n);
int FindMax(int *p, int m, int n, int *pRow, int *pCol);
int main(void)
{
int num[N][N] = {0};
int m, n, ret, prow, pcol;
printf( "Input m,n:\n");
scanf("%d,%d",&m,&n);
int *p = *num;
InputArray(p,m,n);
ret = FindMax(p, m, n, &prow, &pcol);
printf("max=%d,row=%d,col=%d\n", ret, prow, pcol);
return 0;
}
void InputArray(int *p, int m, int n)
{
int i, j;
printf( "Input %d*%d array:\n",m,n);
for(i = 0; i < m; i++)
{
for(j = 0; j < n; j++)
{
scanf("%d",p + i*N + j);
}
}
}
int FindMax(int *p, int m, int n, int *pRow, int *pCol)
{
*pRow = 0;
*pCol = 0;
int max = *p;
for(int i = 0; i < m; i++)
for(int j = 0; j < n; j++)
{
if(max < *(p + i*N + j))
{
*pRow = i;
*pCol = j;
max = *(p + i*N +j);
}
}
return max;
}
7. 冒泡排序
題目內容:
採用冒泡法進行升序排序法的基本原理是:對數組中的n個數執行n-1遍檢查操作,在每一遍執行時,對數組中剩餘的尚未排好序的元素進行如下操作:對相鄰的兩個元素進行比較,若排在後面的數小於排在前面的數,則交換其位置,這樣每一遍操作中都將參與比較的數中的最大的數沉到數組的底部,經過n-1遍操作後就將全部n個數按從小到大的順序排好序了。
#include<stdio.h>
void BubbleSort(int a[],int n);
int main(void)
{
int n;
printf("Input n:");
scanf("%d", &n);
int a[n];
printf("Input %d numbers:", n);
for(int i = 0; i < n; i++)
scanf("%d",&a[i]);
BubbleSort(a, n);
printf("Sorting results:");
for(int i = 0; i < n; i++)
printf("%4d", *(a + i));
return 0;
}
void BubbleSort(int a[],int n)
{
int i, j;
int flag;
for(i = 0; i < n - 1 ; i++)
{
flag = 0;
for(j = 0; j < n - 1; j++)
{
if(*(a + j) > *(a + j + 1))
{
flag = 1;
int temp;
temp = *(a + j);
*(a + j) = *(a + j + 1);
*(a + j + 1) = temp;
}
}
if(flag == 0)
break;
}
}
8. 刪除字符串中與某字符相同的字符
題目內容:
在字符串中刪除與某字符相同的字符,要求用字符數組作函數參數。
#include<stdio.h>
#include<string.h>
#define N 100
void Delete_X(char *str,char *pstr, char ch);
int main(void)
{
char str[N],pstr[N];
char *fir = str;
char *sec = pstr;
char ch;
memset(str,'\0',sizeof(str));
memset(pstr,'\0',sizeof(pstr));
printf("Input a string:\n");
gets(fir);
printf("Input a character:\n");
ch = getchar();
Delete_X(fir,sec,ch);
printf("Results:%s\n",pstr);
return 0;
}
void Delete_X(char *str,char *pstr,char ch)
{
int i = 0, j = 0;
char *fir = str;
char *sec = pstr;
while(*(fir + i) != '\0')
{
if(*(fir + i) != ch)
{
*(sec + j) = *(fir + i);
j++;
}
i++;
}
}
9. 求最大數和最小數的最大公約數
題目內容:
從鍵盤輸入10個正整數,求出最大數,最小數,以及他們的最大公約數。要求用數組實現。
#include<stdio.h>
int gcd(int a,int b);
void Find_max_min(int a[],int *max,int *min);
int main(void)
{
int num[10] = {0};
int max,min,ret;
printf("Input 10 numbers:\n");
for(int i = 0; i < 10; i++)
scanf("%d",&num[i]);
Find_max_min(num,&max,&min);
ret = gcd(max,min);
printf("maxNum=%d\n",max);
printf("minNum=%d\n",min);
if(ret)
printf("%d",ret);
return 0;
}
int gcd(int a,int b)
{
int r;
if(a > 0 && b > 0)
{
while(b != 0)
{
r = a%b;
a = b;
b = r;
}
return a;
}
else
return 0;
}
void Find_max_min(int a[],int *max,int *min)
{
*max = a[0];
*min = a[0];
for(int i = 0; i < 10; i++)
{
if(*max < a[i])
{
*max = a[i];
}
if(*min > a[i])
{
*min = a[i];
}
}
}
10. 數列合併
題目內容:
已知兩個不同長度的降序排列的數列(假設序列的長度都不超過5),請編程將其合併爲一個數列,使合併後的數列仍保持降序排列。
函數原型: void Merge(int a[], int b[], int c[], int m, int n);
函數功能: 將兩個長度分別爲m和n、降序排列的子序列a和b合併後放到數組c中
#include<stdio.h>
#define N 5
void Merge(int a[], int b[], int c[], int m, int n);
int main(void)
{
int m,n;
int a[N] = {0};
int b[N] = {0};
int c[N*2] = {0};
printf("Input m,n:");
scanf("%d,%d", &m, &n);
printf("Input array a:");
for(int i = 0; i < m; i++)
scanf("%d",&a[i]);
printf("Input array b:");
for(int i = 0; i < n; i++)
scanf("%d", &b[i]);
Merge(a,b,c,m,n);
for(int i = 0; i <(m + n); i++)
printf("%4d",c[i]);
return 0;
}
void Merge(int a[], int b[], int c[], int m, int n)
{
int i = 0;
int j = 0;
int k = 0;
while(i < m && j < n)
{
if(a[i] >= b[j])
{
c[k++] = a[i++];
}
else
{
c[k++] = b[j++];
}
}
while(i < m)
c[k++] = a[i++];
while(j < n)
c[k++] = b[j++];
}