PTA - No.9 - 12道題總結
這周的程式設計題還是有點難度的,而且程式碼有的比較長不好截圖分享到群相簿,發文本又太沒意思,就直接一起記錄在一個部落格裡好了:(所有的程式都只需要 #include <stdio.h> 所以不每個都寫了)
7-1 查詢整數 (10 分)
本題要求從輸入的N個整數中查詢給定的X。如果找到,輸出X的位置(從0開始數);如果沒有找到,輸出“Not Found”。
輸入格式:
輸入在第一行中給出兩個正整數N(≤20)和X,第二行給出N個整數。數字均不超過長整型,其間以空格分隔。
輸出格式:
在一行中輸出X的位置,或者“Not Found”。
輸入樣例1: 5 7
3 5 7 1 9
輸出樣例1: 2
輸入樣例2: 5 7
3 5 8 1 9
輸出樣例2: Not Found
int main() { int N, X, t, i; scanf("%d%d", &N, &X); for(i = 0; i < N; i++) { scanf("%d", &t); if(t == X) { printf("%d\n", i); break; } } if(i == N) printf("Not Found\n"); return 0; }
7-2 將陣列中的數逆序存放 (20 分)
將給定的n個整數存入陣列中,將陣列中的這n個數逆序存放,再按順序輸出陣列中的元素。
輸入格式:
輸入在第一行中給出一個正整數n(1≤n≤10)。第二行輸入n個整數,用空格分開。
輸出格式:
在一行中輸出這n個整數的處理結果,相鄰數字中間用一個空格分開,行末不得有多餘空格。
輸入樣例: 4
10 8 1 2
輸出樣例: 2 1 8 10
int main() { int n, a[10]; scanf("%d", &n); for(int i = 0; i < n; i++) scanf("%d", &a[i]); for(int i = n - 1; i > 0; i--) printf("%d ", a[i]); printf("%d\n", a[0]); // 行末不得有多餘空格 return 0; }
7-3 選擇法排序 (20 分)
本題要求將給定的n個整數從大到小排序後輸出。
輸入格式:
輸入第一行給出一個不超過10的正整數n。第二行給出n個整數,其間以空格分隔。
輸出格式:
在一行中輸出從大到小有序的數列,相鄰數字間有一個空格,行末不得有多餘空格。
輸入樣例:4
5 1 7 6
輸出樣例:7 6 5 1
int main()
{
int n, a[10];
scanf("%d", &n);
for(int i = 0; i < n; i++) scanf("%d", &a[i]); // 先全讀進來
for(int i = 0; i < n - 1; i++) // 每次選一個最小的和有序列後一位交換
{
int minV = a[i], minIdx = i; // 最小值,最小值位置
for(int j = i + 1; j < n; j++)
if(a[j] < minV)
{
minV = a[j];
minIdx = j;
}
if(minIdx != i)
{
int tmp = a[i];
a[i] = a[minIdx];
a[minIdx] = tmp;
}
}
for(int i = n - 1; i > 0; i--)
printf("%d ", a[i]);
printf("%d\n", a[0]); // 行末不得有多餘空格
return 0;
}
7-4 交換最小值和最大值 (15 分)
先將輸入的一系列整數中的最小值與第一個數交換,然後將最大值與最後一個數交換,最後輸出交換後的序列。
注意:題目保證最大和最小值都是唯一的。
輸入格式:
輸入在第一行中給出一個正整數N(≤10),第二行給出N個整數,數字間以空格分隔。
輸出格式:
在一行中順序輸出交換後的序列,每個整數後跟一個空格。
輸入樣例:5
8 2 5 1 4
輸出樣例:1 2 5 4 8
int main()
{
int n, a[10];
scanf("%d", &n);
for (int i = 0; i < n; i++) scanf("%d", &a[i]);
int max = -1, maxi = -1, min = 2147483647, mini = -1; // INT_MAX
for(int i = 0; i < n; i++)
if(a[i] < min)
{
min = a[i];
mini = i;
}
a[mini] = a[0];
a[0] = min;
for(int i = 0; i < n; i++) // 必須重新計算,因為交換min之後,最大值位置可能變了
if(a[i] > max)
{
max = a[i];
maxi = i;
}
a[maxi] = a[n - 1];
a[n - 1] = max;
for(int i = 0; i < n; i++)
printf("%d ", a[i]);
return 0;
}
7-5 簡化的插入排序 (15 分)
本題要求編寫程式,將一個給定的整數插到原本有序的整數序列中,使結果序列仍然有序。
輸入格式:
輸入在第一行先給出非負整數N(<10);第二行給出N個從小到大排好順序的整數;第三行給出一個整數X。
輸出格式:
在一行內輸出將X插入後仍然從小到大有序的整數序列,每個數字後面有一個空格。
輸入樣例:
5
1 2 4 5 7
3
輸出樣例:
1 2 3 4 5 7
int main()
{
int N, a[10], X;
scanf("%d", &N);
for(int i = 0; i < N; i++)
scanf("%d", &a[i]);
scanf("%d", &X);
int i;
for(i = 0; i < N; i++)
if(a[i] > X)
{
for(int j = N; j > i; j--)
a[j] = a[j - 1];
a[i] = X;
break;
}
if(i == N) // 都比X小
a[N] = X;
for(int i = 0; i <= N; i++)
printf("%d ", a[i]); // 每個數字後面有一個空格
return 0;
}
7-6 求一批整數中出現最多的個位數字 (20 分)
給定一批整數,分析每個整數的每一位數字,求出現次數最多的個位數字。例如給定3個整數1234、2345、3456,其中出現最多次數的數字是3和4,均出現了3次。
輸入格式:
輸入在第1行中給出正整數N(≤1000),在第二行中給出N個不超過整型範圍的非負整數,數字間以空格分隔。
輸出格式:
在一行中按格式“M: n1 n2 ...”輸出,其中M是最大次數,n1、n2、……為出現次數最多的個位數字,按從小到大的順序排列。數字間以空格分隔,但末尾不得有多餘空格。
輸入樣例:
3
1234 2345 3456
輸出樣例:
3: 3 4
int main()
{
int N, a[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, maxTime = 0;
scanf("%d", &N);
for (int i = 0; i < N; i++)
{
int t;
scanf("%d", &t); // 非負整數
do
{
++a[t % 10];
t /= 10;
} while (t != 0) // do while處理數字為0的情況
}
for (int i = 0; i < 10; i++)
if (a[i] > maxTime)
maxTime = a[i];
printf("%d:", maxTime);
for (int i = 0; i < 10; i++)
if (a[i] == maxTime)
printf(" %d", i);
return 0;
}
7-7 輸出陣列元素 (15 分)
本題要求編寫程式,對順序讀入的n個整數,順次計算後項減前項之差,並按每行三個元素的格式輸出結果。
輸入格式:
輸入的第一行給出正整數n(1<n≤10)。隨後一行給出n個整數,其間以空格分隔。
輸出格式:
順次計算後項減前項之差,並按每行三個元素的格式輸出結果。數字間空一格,行末不得有多餘空格。
輸入樣例:
10
5 1 7 14 6 36 4 28 50 100
輸出樣例:
-4 6 7
-8 30 -32
24 22 50
int main()
{
int N, a[10];
scanf("%d", &N);
for (int i = 0; i < N; i++) scanf("%d", &a[i]); // n個整數
for(int i = 0; i < N - 1; i++)
{
printf("%d", a[i + 1] - a[i]);
if((i + 1) % 3 == 0 || i == N - 2) printf("\n");
else printf(" ");
}
return 0;
}
7-8 找出不是兩個陣列共有的元素 (20 分)
給定兩個整型陣列,本題要求找出不是兩者共有的元素。
輸入格式:
輸入分別在兩行中給出兩個整型陣列,每行先給出正整數N(≤20),隨後是N個整數,其間以空格分隔。
輸出格式:
在一行中按照數字給出的順序輸出不是兩陣列共有的元素,數字間以空格分隔,但行末不得有多餘的空格。題目保證至少存在一個這樣的數字。同一數字不重複輸出。
輸入樣例:
10 3 -5 2 8 0 3 5 -15 9 100
11 6 4 8 2 6 -5 9 0 100 8 1
輸出樣例:
3 5 -15 6 4 1
解:
這道題網上很多答案用了三個陣列,我用了一個數組,flag陣列是用來代替陣列刪除操作的,不怎麼影響時間複雜度。
int main()
{
int an, ancnt, bn, tmp, cnt = 0, first = 1;
// C static陣列預設全初始化為0, flag[i]為0表示res[i]這位數不輸出
static int res[40], flag[40]; // 用flag陣列代替刪除操作
scanf("%d", &an);
ancnt = an;
for (int i = 0; i < an; i++) // 讀第一個陣列, 跳過重複的
{
scanf("%d", &tmp);
int j = 0;
for (j = 0; j < cnt; j++)
if (flag[j] == 1 && res[j] == tmp)
break;
if (j == cnt)
{
res[cnt] = tmp;
flag[cnt] = 1;
++cnt;
}
else
--ancnt; // 記錄第一個陣列存入res多少個數!!
}
scanf("%d", &bn);
for (int i = 0; i < bn; i++) // 讀第二個陣列, res中出現過的話,對應位flag歸0,繼續下一個數
{
scanf("%d", &tmp);
int j = 0;
for (j = 0; j < cnt; j++)
if (res[j] == tmp) // 這裡不能判斷flag!!!!!!因為只要出現過就一定不需要了
break;
if (j == cnt) // res中沒出現過
{
res[cnt] = tmp;
flag[cnt] = 1;
++cnt;
}
else if (j < ancnt) // 在第一個陣列中出現過
flag[j] = 0;
// 在第二個陣列中重複了就直接跳過
}
for (int i = 0; i < 40; i++)
if(flag[i] == 1 && first == 1)
{
printf("%d", res[i]);
first = 0;
}
else if(flag[i] == 1)
printf(" %d", res[i]);
return 0;
}
7-9 求整數序列中出現次數最多的數 (15 分)
本題要求統計一個整型序列中出現次數最多的整數及其出現次數。
輸入格式:
輸入在一行中給出序列中整數個數N(0 < N ≤ 1000),以及N個整數。數字間以空格分隔。
輸出格式:
在一行中輸出出現次數最多的整數及其出現次數,數字間以空格分隔。題目保證這樣的數字是唯一的。
輸入樣例:
10 3 2 -1 5 3 4 3 0 3 2
輸出樣例:
3 4
int main()
{
int N = 0, num = 0, a[1000], maxTime = -1, maxIdx = -1;
static int cnt[1000];
scanf("%d", &N);
for (int i = 0; i < N; i++)
{
int tmp, j;
scanf("%d", &tmp);
for (j = 0; j < num; j++)
if (a[j] == tmp)
{
++cnt[j];
break;
}
if (j == num)
{
a[num] = tmp;
cnt[num] = 1;
++num;
}
if (cnt[j] > maxTime)
{
maxTime = cnt[j];
maxIdx = j;
}
}
printf("%d %d\n", a[maxIdx], maxTime);
return 0;
}
7-10 求最大值及其下標 (20 分)
找出給定的n個數中的最大值及其對應的最小下標(下標從0開始)。
輸入格式:
輸入在第一行中給出一個正整數n(1<n≤10)。第二行輸入n個整數,用空格分開。
輸出格式:
在一行中輸出最大值及最大值的最小下標,中間用一個空格分開。
輸入樣例:
6
2 8 10 1 9 10
輸出樣例:
10 2
int main()
{
int n, tmp, maxV = -2147483648, maxIdx = -1;
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
scanf("%d", &tmp);
if(tmp > maxV)
{
maxV = tmp;
maxIdx = i;
}
}
printf("%d %d\n", maxV, maxIdx);
return 0;
}
7-11 特殊a串數列求和 (20 分)
給定兩個均不超過9的正整數a和n,要求編寫程式求a+aa+aaa++⋯+aa⋯a(n個a)之和。
輸入格式:
輸入在一行中給出不超過9的正整數a和n。
輸出格式:
在一行中按照“s = 對應的和”的格式輸出。
輸入樣例:
2 3
輸出樣例:
s = 246
int main()
{
int a, n, sum = 0;
scanf("%d%d", &a, &n);
// 2 + 22 + 222 就是一個200,兩個20,三個2
for(int i = 1; i <= n; i++)
sum += a * (int)pow(10, n - i) * i;
printf("s = %d\n", sum);
return 0;
}
7-12 兔子繁衍問題 (15 分)
一對兔子,從出生後第3個月起每個月都生一對兔子。小兔子長到第3個月後每個月又生一對兔子。假如兔子都不死,請問第1個月出生的一對兔子,至少需要繁衍到第幾個月時兔子總數才可以達到N對?
輸入格式:
輸入在一行中給出一個不超過10000的正整數N。
輸出格式:
在一行中輸出兔子總數達到N最少需要的月數。
輸入樣例:
30
輸出樣例:
9
解:
這道題其實手算幾個之後就找到規律了,其實就是斐波那契數列:
第幾個月:1、2、3、4、5
幾對兔子:1、1、2、3、5
int main()
{
int n, f1 = 1, f2 = 1, months = 0;
scanf("%d", &n);
for (months = 1;; months++)
{
if(f1 >= n)
{
printf("%d\n", months);
return 0;
}
f2 = f1 + f2;
f1 = f2 - f1;
}
return 0;
}