C語言程序設計之 數組2020-10-28 整理:
第一題:求最小數與第一個數交換
【問題描述】
輸入一個正整數n (1<n<=100),再輸入n個整數,將最小值與第一個數交換,然后輸出交換后的n 個數。
【輸入形式】
第一行,一個正整數n
第二行,n個由空格隔開的整數
【輸出形式】
最小數與第一個數交換后的n的整數
【樣例輸入】
5
8 2 5 1 4
【樣例輸出】
1 2 5 8 4
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n,i,j,k;
int x[100];
scanf("%d",&n);
//數組元素
for(i=0;i<n;i++){
scanf("%d",&x[i]);
}
//printf("%d",t);
k = 0;
for(j=1;j<n;j++){
if(x[k]>x[j]){
k=j;
}
}
//交換
int t = x[0];
x[0] = x[k];
x[k] = t;
for(k=0;k<n;k++){
printf("%d ",x[k]);
}
return 0;
}
解釋:
數組循環存儲不解釋,很好理解;
首先我們假設最小值的下標為0,即:k=0;
我們所需要做的就是把后面的數與最小值進行比較,如果還有比最小值小的值,則交換下標;
k = 0;
for(j=1;j<n;j++){
if(x[k]>x[j]){
k=j;
}
}
找到最小值的下標,也就找到了最小值的值,然后進行最小值與第一個數進行交換;
//交換
int t = x[0];
x[0] = x[k];
x[k] = t;
兩個元素的交換需要通過中間變量(t)來存儲,要不然會有數據被覆蓋掉,得不到正確的值;
最好循環遍歷整個數組即可。
第二題:求一組數的編號
【問題描述】
對數組A中的N(0<N<100)個互不相同的整數從小到大進行連續編號,要求不能改變數組A中元素的順序。
如A=(78,42,-34,94,25)則輸出為(4,3,1,5,2)。個數N和數組中元素要求從鍵盤輸入。
【輸入形式】
第一行,一個整數N
第二行n個空格隔開的整數
【輸出形式】
按順序輸出每個整數的編號,編號間用逗號分隔
【樣例輸入】
5
78 42 -34 94 25
【樣例輸出】
4,3,1,5,2
#include <stdio.h>
int main() {
int x[100];
int a[100];
int n;
int num;
int count=0;
scanf("%d",&n);
//輸入數據存入數組中
for (int i = 0; i < n; ++i) {
scanf("%d",&x[i]);
//初始化
a[i]=1;
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (x[i]>=x[j]){
num ++;
}
}
a[i] =num;
num =0;
}
for (int i = 0; i < n; ++i) {
count++;
if(count==n){
printf("%d",a[i]);
} else{
printf("%d,",a[i]);
}
}
return 0;
}
解釋:
判斷元素的編號,實際是比大小;
定義兩個數組,一個存儲輸入的元素,一個存儲記錄比較的次數;
對兩個數組進行初始化;
兩層循環,將第一個元素與每個元素進行比較,如果符合條件的進行記錄num++;
每次結束后在第一層循環里記錄num的值,並保存到a[]數組中;
將num清零,重復上述操作;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (x[i]>=x[j]){
num ++;
}
}
a[i] =num;
num =0;
}
為了滿足輸出的操作,需要輸出a[]數組時判斷最后的值,
for (int i = 0; i < n; ++i) {
count++;
if(count==n){
printf("%d",a[i]);
} else{
printf("%d,",a[i]);
}
}
第三題:跳一跳
【問題描述】跳一跳規則如下:玩家每次從當前方塊跳到下一個方塊,如果沒有跳到下一個方塊上則游戲結束。 如果跳到了方塊上,但沒有跳到方塊的中心則獲得1分;跳到方塊中心時,若上一次的得分為1分或這是本局游戲的第一次跳躍則此次得分為2分,否則此次得分比上一次得分多兩分(即連續跳到方塊中心時,總得分將+2,+4,+6,+8...)。
現在給出一個人跳一跳的全過程,請你求出他本局游戲的得分(按照題目描述的規則)。
【輸入格式】
輸入包含多個數字,用空格分隔,每個數字都是1,2,0之一,1表示此次跳躍跳到了方塊上但是沒有跳到中心,2表示此次跳躍跳到了方塊上並且跳到了方塊中心,0表示此次跳躍沒有跳到方塊上(此時游戲結束)。
【輸入形式】對於所有評測用例,輸入的數字不超過30個,保證0正好出現一次且為最后一個數字。
【輸出形式】一個整數,表示得分。
【樣例輸入】1 1 2 2 2 1 1 2 2 0
【樣例輸出】22
【樣例說明】22=1+1+2+4+6+ 1+1+2+4
#include <stdio.h>
int main() {
int n;
//統計得分,記錄得分個數
int sum=0,temp=0;
//題目知不超過30
for (int i = 0; i<30; i++) {
scanf("%d",&n);
if(n==0){
break;
}
if (n==1){
//計數清零
temp=0;
sum +=1;
}
if(n==2){
temp +=1;
sum +=temp*2;
}
}
printf("%d",sum);
return 0;
}
解釋:
判斷個數問題;
如果:
- =0:退出循環
- =1:統計得分,得分個數初始化為0,為后面=2做准備
- =2:統計得分個數,累加2與得分個數的乘積
第四題:開燈問題
【問題描述】有n盞燈,編號為1-n。第一個人把所有燈打開,第2個人按下所有編號為2倍數的開關(這些燈將被關掉),第3個人按下所有編號為3的倍數的開關(其中關掉的燈將被打開,開着的燈將被關閉),依此類推。一共有k個人,問最后有哪些燈開着?
輸入 n和k,輸出開着燈的編號。
【輸入形式】兩個整數用空格隔開
【輸出形式】輸出開着燈的編號,編號間用空隔隔開
【樣例輸入】
7 3
【樣例輸出】
1 5 6 7
【樣例說明】K<=n<=1000
#include <stdio.h>
#include "math.h"
int main() {
//n個燈,m個人
int n,m;
int x[10000]={0};
int a=1;
scanf("%d %d",&n,&m);
for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
if (j%i==0){
//取反操作
x[j] = !x[j];
}
}
}
for (int i = 1; i <= n; ++i) {
if (x[i] !=0){
if (a) a=0;
printf("%d ",i);
}
}
return 0;
}
開燈問題,這題沒怎么理解明白,且網上版本眾多,各博主寫的也更加詳細與理解,這里就不班門弄斧了;
還需要自己理解清楚后在添加解釋。
第五題:CCF 201712-1 最小差值
【問題描述】
給定n個數,請找出其中相差(差的絕對值)最小的兩個數,輸出它們的差值的絕對值。
【輸入形式】
輸入第一行包含一個整數n。
第二行包含n個正整數,相鄰整數之間使用一個空格分隔。
【輸出形式】
輸出一個整數,表示答案。
【樣例輸入】
5
1 5 4 8 20
【樣例輸出】
1
【樣例說明】
相差最小的兩個數是5和4,它們之間的差值是1。
【樣例輸入】
5
9 3 6 1 3
【樣例輸出】
0
【樣例說明】
有兩個相同的數3,它們之間的差值是0。
【評分標准】
對於所有評測用例,2 ≤ n ≤ 1000,每個給定的整數都是不超過10000的正整數。
#include <stdio.h>
#include "math.h"
int main() {
int n;
int x[1000];
int min;
//數組存儲
scanf("%d",&n);
for (int i = 0; i < n; i++) {
scanf("%d",&x[i]);
}
//設第一個差為最小值
min = abs(x[1]-x[0]);
for (int i = 0; i < n; i++) {
for (int j = i+1; j < n; j++) {
//絕對值
if (abs(x[j]-x[i])<min){
min = abs(x[j]-x[i]);
}
}
}
printf("%d",min);
return 0;
}
解釋:
該題邏輯與第一題相似,都是假設最小值,然后進行比較,不過這題的最小值是兩個差;
原理都是一樣,其中點出abs是絕對值的意思;
第一題是通過下標,這題是通過值;
不多解釋,不明白可會看第一題解題思路;
第六題:求最大最小數的差
【問題描述】
編程實現如下的功能:取出一個十進制正整數中的所有偶數數字,用這些數字拼成一個最大整數max,取出這個十進制正整數中的所有奇數數字,用這些數字拼成一個最小整數min,計算max和min的差並輸出。
【輸入形式】輸入一行一個十進制整數
【輸出形式】輸出一行一個符合規定的整數
【樣例輸入】
74958106
【樣例輸出】
7061
【樣例說明】max為8640,min為1579,差為7061
#include <stdio.h>
#include "math.h"
int main() {
int n;
int x[100];
int k;
scanf("%d",&n);
int num=0;
while (n != 0){
k = n%10;
x[num] = k;
n = (n-k)/10;
num ++;
}
//對列表排序--選擇排序
for (int i = 0; i < num-1; ++i) {
int min =i;
for (int j = i+1; j < num; ++j) {
if (x[min]>x[j]){
min=j;
}
}
if (min != i){
int t = x[i];
x[i] = x[min];
x[min] = t;
}
}
//查看數組順序
// for (int i = 0; i < num; ++i) {
// printf("%d",x[i]);
// }
// printf("\n");
int sum1=1;
int minnum = 0;
int maxnum = 0;
//判斷偶數
for (int i = 0; i <num; i++) {
if(x[i]%2 == 0 || x[i]==0){
maxnum+=x[i]*sum1;
sum1 *=10;
}
}
//判斷奇數
int sum2=1;
for (int i = num-1; i >=0; i--) {
// printf("%d",i);
if(x[i]%2 != 0){
minnum += x[i]*sum2;
sum2 *=10;
}
}
// printf("%d %d %d",maxnum,minnum,maxnum-minnum);
printf("%d",maxnum-minnum);
return 0;
}
解釋:
首先我們需要明確怎么把輸入的一串數字化為單個元素保存到數組中;
可以將每個元素(x)使用10取余得到的尾數存到數組中,再/10縮小范圍,直到x=0,結束循環;
scanf("%d",&n);
int num=0;
while (n != 0){
k = n%10;
x[num] = k;
n = (n-k)/10;
num ++;
}
然后需要了解數組/列表(python)中的排序問題;
該題在數組排序中我們采用選擇排序;
for (int i = 0; i < num-1; ++i) {
int min =i;
for (int j = i+1; j < num; ++j) {
if (x[min]>x[j]){
min=j;
}
}
if (min != i){
int t = x[i];
x[i] = x[min];
x[min] = t;
}
}
數組排序完成后,開始進行奇偶數的判斷,將滿足條件的元素分別累加乘積;
其中0算在偶數當中;
判斷奇數需要翻轉數組輸出;
//判斷偶數
for (int i = 0; i <num; i++) {
if(x[i]%2 == 0 || x[i]==0){
maxnum+=x[i]*sum1;
sum1 *=10;
}
}
//判斷奇數
int sum2=1;
for (int i = num-1; i >=0; i--) {
//printf("%d",i);
if(x[i]%2 != 0){
minnum += x[i]*sum2;
sum2 *=10;
}
}
拓展:
選擇排序之前python表達的:https://www.cnblogs.com/xbhog/p/11741094.html
總結:
上述題目的解不是唯一,例題中的解是我所理解並運行成功的,如果有不對的地方,歡迎指出。