1.密碼破譯
要將"China"譯成密碼,譯碼規律是:用原來字母后面的第4個字母代替原來的字母。
例如,字母"A"後面第4個字母是"E"."E"代替"A"。因此,"China"應譯為"Glmre"。
請編一程式,用賦初值的方法使cl、c2、c3、c4、c5五個變數的值分別為,’C’、’h’、’i’、’n’、’a’,經過運算,使c1、c2、c3、c4、c5分別變為’G’、’l’、’m’、’r’、’e’,並輸出。
測試輸入:China
測試輸出:Glmre
#include <stdio.h>
int main(){
char s[11];
gets(s); //輸入字串
for (int i = 0; s[i] != '\0'; i++){
if (s[i] >= 'A' && s[i] <= 'Z'){ //判斷是否為大寫字母
s[i] = (s[i] + 4 - 'A') % 26 + 'A'; //大寫字母后移
}
if (s[i] >= 'a' && s[i] <= 'z'){ //判斷是否為小寫字母
s[i] = (s[i] + 4 - 'a') % 26 + 'a'; //小寫字母后移
}
}
puts(s); //輸出字串
return 0;
}
2.最大公約數與最小公倍數
輸入兩個正整數m和n,求其最大公約數和最小公倍數。
測試輸入:12,8
測試輸出:4,24
#include <stdio.h>
int main(){
int n, m, r, p;
scanf("%d,%d", &n, &m);
if(n < m){ //確保 n 比 m 大
int temp = n;
n = m;
m = temp;
}
p = n * m;
while(m != 0){
r = n%m;
n = m;
m = r;
}
printf("最大公約數為: %d\n", n);
printf("最小公倍數為: %d\n", p/n);
return 0;
}
3.字元統計
輸入一行字元,分別統計出其中英文字母、數字、空格和其他字元的個數。
測試輸入:aklsjflj123 sadf918u324 asdf91u32oasdf/.';123
測試輸出:字母數:23,數字數:16,空格數:2,其他數:4
方法一:利用 getchar()
輸入字元。
#include <stdio.h>
int main(){
int letter = 0, number = 0, space = 0, other = 0;
char ch;
while((ch = getchar()) != '\n'){ //讀入字元
if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'))
letter ++;
else if (ch == ' ')
space ++;
else if (ch >= '0' && ch <= '9')
number ++;
else
other ++;
}
printf("字母數:%d,數字數:%d,空格數:%d,其他數:%d", letter, number, space, other);
return 0;
}
方法二:利用 gets()
輸入字串。
#include <stdio.h>
#include <string.h>
char str[200];
int main(){
int letter = 0, number = 0, space = 0, other, n;
gets(str);
n = strlen (str);
for(int i = 0; i < n; i++){
if ((str[i] >= 'A' && str[i] <= 'Z') || (str[i] >= 'a' && str[i] <= 'z'))
letter ++;
else if (str[i] == ' ')
space ++;
else if (str[i] >= '0' && str[i] <= '9')
number ++;
else
other++;
}
printf("字母數:%d,數字數:%d,空格數:%d,其他數:%d", letter, number, space, other);
return 0;
}
4.求和1
求Sn=a+aa+aaa+…+aa…aaa(有n個a)之值,其中a是一個數字。例如: a為2,n=5時,Sn=2+22+222+2222+22222,a,n由鍵盤輸入。
測試輸入:2 5
測試輸出:24690
#include <stdio.h>
int main(){
int a, n, sn = 0, temp = 0;
scanf("%d %d", &a, &n);
for(int i = 0; i < n; i++){
temp += a;
sn += temp;
a *= 10;
}
printf("%d\n", sn);
return 0;
}
5.求和2
求Sn=1!+2!+3!+4!+5!+…+n!之值,其中n是一個數字(n不超過20)。
#include <stdio.h>
int main(){
int n;
long long Sn = 0, temp = 1;
scanf("%d", &n);
for (int i = 1; i <= n; i++){
temp = temp * i;
Sn = Sn + temp;
}
printf("%lld", Sn);
return 0;
}
6.求和3
求以下三數的和, 1a之和,1b的平方和,1~c的倒數和。a,b,c 由鍵盤輸入,保留2位小數。
測試輸入:100 50 10
測試輸出:47977.93
#include <stdio.h>
int main(){
int a, b, c;
double sum1 = 0, sum2 = 0 , sum3 = 0;
scanf("%d %d %d", &a, &b, &c);
for (int i = 1; i <= a; i++)
sum1 += i;
for (int i = 1; i <= b; i++)
sum2 += i * i;
for (double i = 1; i <= c; i++)//i作分母,使用double型別
sum3 += 1/i;
printf("%.2lf", sum1 + sum2 + sum3);
return 0;
}
7.水仙花數
列印出所有"水仙花數",所謂"水仙花數"是指一個三位數,其各位數字立方和等於該本身。 例如:153是一個水仙花數,因為153=13+53+3^3。
測試輸入:無
測試輸出:無
#include<stdio.h>
int main(){
int a,b,c;
for(int i=100; i<1000; i++){
a = i / 100; //百位
b = i / 10 % 10; //十位
c = i % 10; //個位
if(a*a*a + b*b*b + c*c*c == i)
printf("%d ",i);
}
return 0;
}
8.完數
一個數如果恰好等於不包含它本身所有因子之和,這個數就稱為"完數"。 例如,6的因子為1、2、3,而6=1+2+3,因此6是"完數"。 程式設計序找出N之內的所有完數,並按下面格式輸出其因子。
測試輸入:1000
測試輸出:6 its factors are 1 2 3
28 its factors are 1 2 4 7 14
496 its factors are 1 2 4 8 16 31 62 124 248
#include <stdio.h>
int main(){
int N, sum = 0;
scanf( "%d", &N );
for ( int i = 2; i <= N; i++ ){
for ( int j = 1; j <=i/2; j++ ){
if ( i % j == 0 )
sum = sum + j;
}
if ( sum == i ){
printf( "%d its factors are ", i );
for ( int k = 1; k <=i/2; k++ ){
if ( i % k == 0 )
printf( "%d ", k );
}
printf( "\n" );
}
sum = 0;
}
return 0;
}
9.求和4
有一分數序列: 2/1 3/2 5/3 8/5 13/8 21/13...... 求出這個數列的前N項之和,保留兩位小數。
測試輸入:10
測試輸出:16.48
#include<stdio.h>
int main(){
int n;
double sum = 0, a = 2.0, b = 1.0, t;//a為分子,b為分母
scanf("%d", &n);
for(int i = 0; i < n; i++){
sum += a / b;
t = a;
a = a + b;
b = t;
}
printf("%0.2lf", sum);
return 0;
}
10.自由下落的距離計算
一球從M米高度自由下落,每次落地後返回原高度的一半,再落下。 它在第N次落地時反彈多高?共經過多少米? 保留兩位小數。M, N由鍵盤輸入。
測試輸入:1000
測試輸出:5
#include<stdio.h>
int main(){
double M, N;
scanf("%lf %lf", &M, &N);
double sum = M, h = M/2;
for(int i = 1; i < N; i++){
sum += 2*h;
h = h/2;
}
printf("%lf %lf", h, sum);
return 0;
}
11.猴子吃桃
猴子吃桃問題。猴子第一天摘下若干個桃子,當即吃了一半,還不過癮,又多吃了一個。 第二天早上又將剩下的桃子吃掉一半,又多吃一個。以後每天早上都吃了前一天剩下的一半零一個。 到第N天早上想再吃時,見只剩下一個桃子了。求第一天共摘多少桃子。
測試輸入:10
測試輸出:1534
# include <stdio.h>
int main()
{
int sum = 1, n;
scanf("%d", &n);
while(n > 1){ //注意迴圈 n-1 次, 不是n次
sum = (sum + 1) * 2;
n--;
}
printf("%d", sum);
return 0;
}
12.迭代法求平方根
用迭代法求 平方根。
公式:求a的平方根的迭代公式為: X[n+1]=(X[n]+a/X[n])/2 要求前後兩次求出的差的絕對值少於0.00001。 輸出保留3位小數。
#include <stdio.h>
#include <math.h>
int main(){
double a, x0, x1;
scanf("%lf", &a);
x0 = a/2;
x1 = (x0 + a/x0)/2;
while(fabs(x1-x0) > 1e-5){
x0 = x1;
x1 = (x0 + a/x0)/2;
}
printf("%0.3lf", x1);
return 0;
}
13求N以內的素數
求N以內的素數。
測試輸入:10
測試輸出:
2
3
5
7
#include <stdio.h>
#include <math.h>
int main(){
int N, isPrime = 1;
scanf("%d", &N);
for(int i = 2; i <= N; i++){//因為 1 不是素數,i 從 2 開始
isPrime = 1;
for(int j = 2; j <= sqrt(i); j++){
if(i % j == 0){
isPrime = 0;
}
}
if(isPrime == 1)
printf("%d\n", i);
}
return 0;
}
14.選擇排序
輸入10個數,用選擇法對10個整數從小到大排序。
測試輸入:4 85 3 234 45 345 345 122 30 12
測試輸出:3 4 12 30 45 85 122 234 345 345
#include <stdio.h>
void Select_Sort(int a[], int len) {
int min, temp;
for (int i = 0 ; i < len - 1 ; i++){
min = i; // 記錄最小值,第一個元素預設最小
for (int j = i + 1; j < len; j++){ // 訪問未排序的元素
if (a[j] < a[min]){ // 找到目前最小值
min = j; // 記錄最小值
}
}
if(min != i){
temp = a[min]; // 交換兩個變數
a[min] = a[i];
a[i] = temp;
}
}
}
int main(){
int a[10];
for(int i = 0; i < 10; i++)
scanf("%d", &a[i]);
Select_Sort(a, 10);
for(int i = 0; i < 10; i++)
printf("%d ", a[i]);
return 0;
}
15.氣泡排序
輸入10個數,用選擇法對10個整數從小到大排序。
測試輸入:4 85 3 234 45 345 345 122 30 12
測試輸出:3 4 12 30 45 85 122 234 345 345
#include <stdio.h>
void Bubble_Sort(int a[], int len){
int temp;
for (int i = 0; i < len - 1; i++){
for (int j = 0; j < len - 1 - i; j++){
if (a[j] > a[j + 1]){
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
}
int main(){
int a[10];
for(int i = 0; i < 10; i++)
scanf("%d", &a[i]);
Bubble_Sort(a, 10);
for(int i = 0; i < 10; i++)
printf("%d ", a[i]);
return 0;
}
16.直接插入排序
輸入10個數,用選擇法對10個整數從小到大排序。
測試輸入:4 85 3 234 45 345 345 122 30 12
測試輸出:3 4 12 30 45 85 122 234 345 345
#include <stdio.h>
void Insert_Sort(int a[], int len){
int temp, j;//將 j 定義在for迴圈外,後面要用到 j
for (int i = 1; i < len; i++){
temp = a[i];
for (j = i; j > 0 && a[j-1] > temp; j--){
a[j] = a[j-1];
}
a[j] = temp;
}
}
int main(){
int a[10];
for(int i = 0; i < 10; i++)
scanf("%d", &a[i]);
Insert_Sort(a, 10);
for(int i = 0; i < 10; i++)
printf("%d ", a[i]);
return 0;
}
17.二分查詢(折半查詢)
查詢 target 在有序陣列中的下標。陣列長度n,有序陣列中的n個元素,target 均由鍵盤輸入。
測試輸入1:
4
1 2 3 4
4
測試輸出1:4在陣列中的下標為3
測試輸入2:
4
1 2 3 4
0
測試輸出2:陣列中不存在0
#include <stdio.h>
int a[100];
int search(int a[], int n, int target){ //a是陣列,n是陣列a的大小,target是需要查詢的值
int left = 0, right = n - 1;
while (left <= right){ //當left <= right時,區間 [left, right]有效
int mid = (right + left) / 2;
if (a[mid] > target){
right = mid - 1; //target在左區間 [left, mid - 1]
}
else if (a[mid] < target){
left = mid + 1; //target在右區間 [mid + 1, right]
}
else{ //既不在左邊,也不在右邊,那就是找到答案了
return mid; //返回的是 target在陣列中的位置
}
}
//迴圈結束都沒有找到目標值,說明陣列中沒有 target
return -1;
}
int main(){
int n, target, pos;
scanf("%d", &n);
for(int i = 0; i < n; i++)
scanf("%d", &a[i]);
scanf("%d", &target);
pos = search(a, n, target);
if(pos == -1)
printf("陣列中不存在%d\n", target);
else
printf("%d在陣列中的下標為%d\n", target, pos);
return 0;
}
18.矩陣對角線求和
輸入一個3×3矩陣,求主對角線元素之和與副對角線元素之和。
測試輸入:
1 2 3
1 1 1
3 2 1測試輸出:
主對角線之和為 3
副對角線之和為 7
#include<stdio.h>
int main(){
int a[3][3];
int sum1 = 0, sum2 = 0;
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
scanf("%d", &a[i][j]);
}
}
for(int i=0; i<3; i++){
for(int j=0; j<3; j++){
if(i == j) //主對角線
sum1 += a[i][j];
if(i + j == 2) //副對角線
sum2 += a[i][j];
}
}
printf("主對角線之和為 %d\n副對角線之和為 %d\n", sum1, sum2);
return 0;
}
19.陣列插入
已有一個已正序排好的9個元素的陣列,今輸入一個數要求按原來排序的規律將它插入陣列中。
測試輸入:
1 7 8 17 23 24 59 62 101
50測試輸出:
1 7 8 17 23 24 50 59 62 101
#include<stdio.h>
int main(){
int a[10], num;
for(int i = 0; i < 9; i++)
scanf("%d", &a[i]);
scanf("%d", &num);
int j;
for (j = 9; j > 0 && a[j-1] > num; j--){ //直接插入排序的思想
a[j] = a[j-1]; //元素後移
}
a[j] = num;
for(int i = 0; i < 10; i++)
printf("%d ", a[i]);
return 0;
}
20.數字逆序輸出
輸入n個數字,然後逆序輸出。
測試輸入:
10
1 2 3 4 5 6 7 8 9 0
測試輸出:
0 9 8 7 6 5 4 3 2 1
#include<stdio.h>
int a[100];
int main(){
int n;
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]);
return 0;
}
21.二維陣列轉置
寫一個函式,使給定的一個二維陣列(3×3)轉置,即行列互換。
測試輸入:
1 2 3
4 5 6
7 8 9測試輸出:
1 4 7
2 5 8
3 6 9
#include<stdio.h>
int a[3][3];
void convert(int a[][3]){//注意二維陣列作為形參,列數不能省略
int temp;
for(int i = 0; i < 3; i++){
for(int j = i + 1; j < 3; j++){ //j從i + 1開始, 將矩陣上對角線元素與下對角線元素交換
temp = a[i][j];
a[i][j] = a[j][i];
a[j][i] = temp;
}
}
}
int main(){
for(int i = 0; i < 3; i++){ //輸入二維陣列
for(int j = 0; j < 3; j++){
scanf("%d", &a[i][j]);
}
}
convert(a);
for(int i = 0; i < 3; i++){ //輸出二維陣列
for(int j = 0; j < 3; j++){
printf("%d ", a[i][j]);
}
printf("\n");
}
return 0;
}
22.字串反轉
寫一函式,使輸入的一個字串按反序存放,在主函式中輸入和輸出字串。
測試輸入:123456abcdef
測試輸出:fedcba654321
#include <stdio.h>
#include <string.h>
char str[100];
void inverse(char str[]){
int temp, len = strlen(str); //len為字串長度
for(int i = 0; i < len/2; i++){
temp = str[i];
str[i] = str[len-i-1];
str[len-i-1] = temp;
}
}
int main(){
gets(str);
inverse(str);
puts(str);
return 0;
}
23.字串連線
寫一函式,將兩個字串連線。
#include <stdio.h>
#include <string.h>
char s1[100], s2[100], s[200];//連線s1,s2,將結果存入s
void concatenate(char s1[], char s2[], char s[]){
int k = 0; //k為s的下標
for(int i = 0; s1[i] != '\0'; i++)
s[k++] = s1[i];
for(int i = 0; s2[i] != '\0'; i++)
s[k++] = s2[i];
s[k] = '\0'; //在結尾加上結束符
}
int main(){
gets(s1);
gets(s2);
concatenate(s1, s2, s);
puts(s);
return 0;
}
24.數字分離
寫一函式,輸入一個 n 位數字,要求輸出這 n 個數字字元,但每兩個數字間空格。如輸入1990,應輸出"1 9 9 0"。
測試輸入:1990
測試輸出:1 9 9 0
#include <stdio.h>
#include <string.h>
char num[100];
void function(char num[]){
int len = strlen(num);
for(int i = len; i > 0; i--){
num[2*i] = num[i];
num[2*i - 1] = ' ';
}
}
int main(){
gets(num);
function(num);
puts(num);
return 0;
}
25.整數處理
輸入10個整數,將其中最小的數與第一個數對換,把最大的數與最後一個數對換。寫三個函式; ①輸入10個數;②進行處理;③輸出10個數。
測試輸入:2 1 3 4 5 6 7 8 10 9
測試輸出:1 2 3 4 5 6 7 8 9 10
#include <stdio.h>
int a[10];
void input(int a[]){ //輸入函式
for(int i = 0; i < 10; i++)
scanf("%d", &a[i]);
}
void deal(int a[]){ //處理函式
int temp, max = 0, min = 0;//max和min分別記錄最大值和最小值的下標
for(int i = 0; i < 10; i++){
if(a[max] < a[i])
max = i;
}
for(int i = 0; i < 10; i++){
if(a[min] > a[i])
min = i;
}
temp = a[0];//將最小的數與第一個數交換
a[0] = a[min];
a[min] = temp;
temp = a[9];//將最大的數與最後的數交換
a[9] = a[max];
a[max] = temp;
}
void output(int a[]){ //輸出函式
for(int i = 0; i < 10; i++)
printf("%d ", a[i]);
}
int main(){
input(a);
deal(a);
output(a);
return 0;
}
26.數字後移
有n個整數,使前面各數順序向後移m個位置,最後m個數變成前面m個數。寫一函式:實現以上功能,在主函式中輸入n個數和輸出調整後的n個數。
測試輸入:
10
1 2 3 4 5 6 7 8 9 10
2測試輸出:9 10 1 2 3 4 5 6 7 8
#include <stdio.h>
int a[100], b[100];
void function(int a[], int n, int k){
int temp;
for(int i = 0; i < n; i++)
b[(i+k)%n] = a[i];
for(int i = 0; i < n; i++)
a[i] = b[i];
}
int main(){
int n, k; //n 個數,後移 k 位
scanf("%d", &n);
for(int i = 0; i < n; i++){
scanf("%d", &a[i]);
}
scanf("%d", &k);
function(a, n, k);
for(int i = 0; i < n; i++){
printf("%d ", a[i]);
}
return 0;
}
27.字串複製
有一字串,包含n個字元。寫一函式,將此字串中從第m個字元開始的全部字元複製成為另一個字串。鍵盤上輸入順序為:數字n 一行字串 數字m。
測試輸入:
6
abcdef
3測試輸出:cdef
#include <stdio.h>
#include <string.h>
char s1[100], s2[100];
void copy(char s1[], char s2[], int n, int m){
int k = 0;
for(int i = m-1; i < n; i++)
s2[k++] = s1[i];
s2[k] = '\0';
}
int main(){
int n, m;
scanf("%d", &n);
getchar(); //吞掉輸入n之後的回車,不然回車會賦值給s1
gets(s1);
scanf("%d", &m);
copy(s1, s2, n ,m);
puts(s2);
return 0;
}
28.第幾天(使用結構體)
定義一個結構體變數(包括年、月、日)。計算該日在本年中是第幾天,注意閏年問題。
測試輸入:2000 12 19
測試輸出:是第354天
#include <stdio.h>
int mon[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
//每個月的天數
struct y_m_d{ //定義年月日結構體 y_m_d
int year;
int month;
int day;
}data; //定義一個結構體變數,變數名為data,相當於 y_m_d data
//其中 y_m_d相當於資料型別, data為變數名
int main(){
int day_sum = 0;
scanf("%d %d %d", &data.year, &data.month, &data.day);//輸入年月日
if(data.year % 4 == 0) //如果是閏年,2月就要改成29天
mon[1] = 29;
for(int i = 0; i < data.month - 1; i++)//計算第幾天
day_sum += mon[i];
day_sum += data.day;
printf("是第%d天", day_sum);
}
29.結構體之成績統計1
現有有N個學生的資料記錄,每個記錄包括學號、姓名、三科成績。 編寫一個函式input,用來輸入一個學生的資料記錄。 編寫一個函式print,列印一個學生的資料記錄。 在主函式呼叫這兩個函式,讀取N條記錄輸入,再按要求輸出。 N<100
測試輸入:
2
a100 clang 70 80 90
b200 dotcpp 90 85 75測試輸出:
a100,clang,70,80,90,
b200,dotcpp,90,85,75,
#include <stdio.h>
const int N = 100;
struct student{
char num[10]; //學號
char name[10]; //姓名
int score[3]; //三科成績
}stu[N];
void input(int n){ //輸入函式
for(int i = 0; i < n; i++){
scanf("%s", stu[i].num);// gets(stu[i].num)
scanf("%s", stu[i].name);// gets(stu[i].name)
for(int j = 0; j < 3; j++)
scanf("%d", &stu[i].score[j]);
}
}
void print(int n){ //輸出函式
for(int i = 0; i < n; i++){
printf("%s,%s,", stu[i].num, stu[i].name);
for(int j = 0; j < 3; j++)
printf("%d,", stu[i].score[j]);
printf("\n");
}
}
int main(){
int n;
scanf("%d", &n);
input(n);
print(n);
return 0;
}
30.結構體之成績統計2
有10個學生,每個學生的資料包括學號、姓名、3門課的成績,從鍵盤輸入10個學生的資料,要求列印出3門課的總平均成績,以及最高分的學生的資料(包括學號、姓名、3門課成績、平均分)。
測試輸入:
1 a 100 100 100
2 b 90 90 100
3 c 90 100 90
4 d 100 90 90
5 c 100 100 98
6 e 99 98 87
7 ee 99 100 89
10 f 89 87 86
8 bw 10 9 8
9 o 100 0 100測試輸出:
3門課程的總平均分為 83.30
最高分學生資料為:
學號:a,姓名:a,成績:100 100 100,平均成績:100.00
#include <stdio.h>
const int N = 10;
struct student{
char num[10]; //學號
char name[10]; //姓名
int score[3]; //三科成績
double aver; //平均成績
}stu[N];
int main(){
//輸入學生資料
double sum;
//sum記錄每個學生的三科成績總分,用來求該學生平均分
for(int i = 0; i < N; i++){
scanf("%s", stu[i].num);
scanf("%s", stu[i].name);
sum = 0;
for(int j = 0; j < 3; j++){
scanf("%d", &stu[i].score[j]);
sum += stu[i].score[j];
}
stu[i].aver = sum/3.0;
}
//計算總平均分
double sum_aver = 0, aver = 0;
//sum_aver為所有學生的平均分之和,aver為要輸出的總平均分
for(int i = 0; i < N; i++)
sum_aver += stu[i].aver;
aver = sum_aver / N;
printf("3門課程的總平均分為 %.2lf\n", aver);
//輸出最高分學生資料
double max = stu[0].aver;
int max_i = 0;
//max記錄最高平均分,max_i記錄最高分學生下標
for(int i = 0; i < N; i++){
if(stu[i].aver > max){
max = stu[i].aver;
max_i = i;
}
}
printf("最高分學生資料為:\n");
printf("學號:%s,姓名:%s,成績:%d %d %d,平均成績:%.2lf",
stu[max_i].name, stu[max_i].name,
stu[max_i].score[0], stu[max_i].score[1], stu[max_i].score[2], stu[max_i].aver);
return 0;
}
31.約瑟夫環(陣列版)
n個人圍成一圈,從第一個人開始報數,數到 m的人出列,再由下一個人重新從1開始報數,數到 m的人再出圈,依次類推,直到所有的人都出圈,請輸出依次出圈人的編號。
例如 n=13, m=3 時,13個人圍成一圈,從第一個人開始順序報號1,2,3,凡報到 3 者退出圈子,接著下一個人從1開始重新報數,直到所有人退出圈子。
測試輸入:13 3
測試輸出:3 6 9 12 2 5 8 11 1 4 7 10 13
#include <stdio.h>
const int N = 100;
int st[N]; //標記是否出圈
int main(){
int n, m;
scanf("%d %d", &n, &m);
int surplus = n; //surplus為圈中剩餘人數
int i = 0, count = 1;//count為報數,i為第i個人,i從0開始
while(surplus > 0){
if(st[i] == 1) //跳過
i++;
else{
if(count == m){ //出圈
st[i] == 1;
surplus--;
printf("%d ", i+1);
count = 1; //重新計數
i++;
}
else{
count++;
i++;
}
}
if(i == n) i = 0;
}
return 0;
}
32.約瑟夫環(靜態迴圈連結串列版)
#include <stdio.h>
const int N = 100;
struct person{
int number;
int next;
}link[N];
int main(){
int n, m;
scanf("%d %d", &n, &m);
//建立迴圈連結串列
for(int i = 1; i <= n; i++){
link[i].next = i+1;
link[i].number = i;
}
link[n].next = 1; //最後一個元素的next指標指向第一個元素
int surplus = n; //surplus為圈中剩餘人數
int h = 1, count = 1; //count為報數,h為第h個人
while(surplus > 0){
if(link[h].number == 0) //跳過
h = link[h].next;
else{
if(count == m){ //出圈
printf("%d ", link[h].number);
link[h].number = 0; //標記為已出圈
surplus--;
count = 1; //重新計數
h = link[h].next;
}
else{
count++;
h = link[h].next;
}
}
}
return 0;
}