Skip to content

Commit 89375eb

Browse files
committed
继续补充
1 parent 46e577d commit 89375eb

File tree

23 files changed

+1473
-0
lines changed

23 files changed

+1473
-0
lines changed

乱数排列/乱数排列.c

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
洗扑克牌(乱数排列)
3+
说明
4+
洗扑克牌的原理其实与乱数排列是相同的,都是将一组数字(例如1~N)打乱重新排列,只
5+
不过洗扑克牌多了一个花色判断的动作而已。
6+
解法
7+
初学者通常会直接想到,随机产生1~N的乱数并将之存入阵列中,后来产生的乱数存入阵列
8+
前必须先检查阵列中是否已有重复的数字,如果有这个数就不存入,再重新产生下一个数,运
9+
气不好的话,重复的次数就会很多,程式的执行速度就很慢了,这不是一个好方法。
10+
以1~52的乱数排列为例好了,可以将阵列先依序由1到52填入,然后使用一个回圈走访阵列,
11+
并随机产生1~52的乱数,将产生的乱数当作索引取出阵列值,并与目前阵列走访到的值相交换,
12+
如此就不用担心乱数重复的问题了,阵列走访完毕后,所有的数字也就重新排列了。
13+
至于如何判断花色?这只是除法的问题而已,取商数判断花色,取余数判断数字,您可以直接
14+
看程式比较清楚。
15+
*/
16+
17+
#include <stdio.h>
18+
#include <stdlib.h>
19+
#include <time.h>
20+
#define N 52
21+
int main(void) {
22+
int poker[N + 1];
23+
int i, j, tmp, remain;
24+
// 初始化阵列
25+
for(i = 1; i <= N; i++)
26+
poker[i] = i;
27+
srand(time(0));
28+
// 洗牌
29+
for(i = 1; i <= N; i++) {
30+
j = rand() % 52 + 1;
31+
tmp = poker[i];
32+
poker[i] = poker[j];
33+
poker[j] = tmp;
34+
}
35+
for(i = 1; i <= N; i++) {
36+
// 判断花色
37+
switch((poker[i]-1) / 13) {
38+
case 0:
39+
printf("桃"); break;
40+
case 1:
41+
printf("心"); break;
42+
case 2:
43+
printf("砖"); break;
44+
case 3:
45+
printf("梅"); break;
46+
}
47+
// 扑克牌数字
48+
remain = poker[i] % 13;
49+
switch(remain) {
50+
case 0:
51+
printf("K "); break;
52+
case 12:
53+
printf("Q "); break;
54+
case 11:
55+
printf("J "); break;
56+
default:
57+
printf("%d ", remain); break;
58+
}
59+
if(i % 13 == 0)
60+
printf("\n");
61+
}
62+
return 0;
63+
}

二分搜寻法/二分搜寻法.c

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
二分搜寻法(搜寻原则的代表)
3+
说明如果搜寻的数列已经有排序,应该尽量利用它们已排序的特性,以减少搜寻比对的次数,
4+
这是搜寻的基本原则,二分搜寻法是这个基本原则的代表。
5+
解法在二分搜寻法中,从数列的中间开始搜寻,如果这个数小于我们所搜寻的数,由于数列
6+
已排序,则该数左边的数一定都小于要搜寻的对象,所以无需浪费时间在左边的数;如果搜寻
7+
的数大于所搜寻的对象,则右边的数无需再搜寻,直接搜寻左边的数。
8+
所以在二分搜寻法中,将数列不断的分为两个部份,每次从分割的部份中取中间数比对,例如
9+
要搜寻92于以下的数列,首先中间数索引为(0+9)/2 = 4(索引由0开始):
10+
[3 24 57 57 67 68 83 90 92 95]
11+
由于67小于92,所以转搜寻右边的数列:
12+
3 24 57 57 67 [68 83 90 92 95]
13+
由于90小于92,再搜寻右边的数列,这次就找到所要的数了:
14+
3 24 57 57 67 68 83 90 [92 95]
15+
*/
16+
17+
#include <stdio.h>
18+
#include <stdlib.h>
19+
#include <time.h>
20+
#define MAX 10
21+
#define SWAP(x,y) {int t; t = x; x = y; y = t;}
22+
void quicksort(int[], int, int);
23+
int bisearch(int[], int);
24+
int main(void) {
25+
int number[MAX] = {0};
26+
int i, find;
27+
srand(time(NULL));
28+
for(i = 0; i < MAX; i++) {
29+
number[i] = rand() % 100;
30+
}
31+
quicksort(number, 0, MAX-1);
32+
printf("数列:");
33+
for(i = 0; i < MAX; i++)
34+
printf("%d ", number[i]);
35+
printf("\n输入寻找对象:");
36+
scanf("%d", &find);
37+
if((i = bisearch(number, find)) >= 0)
38+
printf("找到数字于索引%d ", i);
39+
else
40+
printf("\n找不到指定数");
41+
printf("\n");
42+
return 0;
43+
}
44+
int bisearch(int number[], int find) {
45+
int low, mid, upper;
46+
low = 0;
47+
upper = MAX - 1;
48+
while(low <= upper) {
49+
mid = (low+upper) / 2;
50+
if(number[mid] < find)
51+
low = mid+1;
52+
else if(number[mid] > find)
53+
upper = mid - 1;
54+
else
55+
return mid;
56+
}
57+
return -1;
58+
}
59+
void quicksort(int number[], int left, int right) {
60+
int i, j, k, s;
61+
if(left < right) {
62+
s = number[(left+right)/2];
63+
i = left - 1;
64+
j = right + 1;
65+
while(1) {
66+
while(number[++i] < s) ; // 向右找
67+
while(number[--j] > s) ; // 向左找
68+
if(i >= j)
69+
break;
70+
SWAP(number[i], number[j]);
71+
}
72+
quicksort(number, left, i-1); // 对左边进行递回
73+
quicksort(number, j+1, right); // 对右边进行递回
74+
}
75+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
产生可能的集合
3+
说明
4+
给定一组数字或符号,产生所有可能的集合(包括空集合), 例如给定1 2 3,则可能的集合为:
5+
{}、{1}、{1,2}、{1,2,3}、{1,3}、{2}、{2,3}、{3}。
6+
解法
7+
如果不考虑字典顺序,则有个简单的方法可以产生所有的集合,思考二进位数字加法,并注意
8+
1出现的位置,如果每个位置都对应一个数字,则由1所对应的数字所产生的就是一个集合,例
9+
如:
10+
了解这个方法之后,剩下的就是如何产生二进位数?有许多方法可以使用,您可以使用unsigned
11+
型别加上&位元运算来产生,这边则是使用阵列搜寻,首先阵列内容全为0,找第一个1,在还
12+
没找到之前将走访过的内容变为0,而第一个找到的0则变为1,如此重复直到所有的阵列元素
13+
都变为1为止,例如:
14+
000 => 100 => 010 => 110 => 001 => 101 => 011 => 111
15+
如果要产生字典顺序,例如若有4个元素,则:
16+
{} => {1} => {1,2} => {1,2,3} => {1,2,3,4} =>
17+
{1,2,4} =>
18+
{1,3} => {1,3,4} =>
19+
{1,4} =>
20+
{2} => {2,3} => {2,3,4} =>
21+
{2,4} =>
22+
{3} => {3,4} =>
23+
000 {}
24+
001 {3}
25+
010 {2}
26+
011 {2,3}
27+
100 {1}
28+
101 {1,3}
29+
110 {1,2}
30+
111 {1,2,3}
31+
{4}
32+
简单的说,如果有n个元素要产生可能的集合,当依序产生集合时,如果最后一个元素是n,而
33+
倒数第二个元素是m的话,例如:
34+
{a b c d e n}
35+
则下一个集合就是{a b c d e+1},再依序加入后续的元素。
36+
例如有四个元素,而当产生{1 2 3 4}集合时,则下一个集合就是{1 2 3+1},也就是{1 2 4},由于
37+
最后一个元素还是4,所以下一个集合就是{1 2+1},也就是{1 3},接下来再加入后续元素4,也
38+
就是{1 3 4},由于又遇到元素4,所以下一个集合是{1 3+1},也就是{1 4}。
39+
*/
40+
41+
#include <stdio.h>
42+
#include <stdlib.h>
43+
#define MAXSIZE 20
44+
int main(void) {
45+
char digit[MAXSIZE];
46+
int i, j;
47+
int n;
48+
printf("输入集合个数:");
49+
scanf("%d", &n);
50+
for(i = 0; i < n; i++)
51+
digit[i] = '0';
52+
printf("\n{}"); // 空集合
53+
while(1) {
54+
// 找第一个0,并将找到前所经过的元素变为0
55+
for(i = 0; i < n && digit[i] == '1'; digit[i] = '0', i++);
56+
if(i == n) // 找不到0
57+
break;
58+
else // 将第一个找到的0变为1
59+
digit[i] = '1';
60+
// 找第一个1,并记录对应位置
61+
for(i = 0; i < n && digit[i] == '0'; i++);
62+
printf("\n{%d", i+1);
63+
for(j = i + 1; j < n; j++)
64+
if(digit[j] == '1')
65+
printf(",%d", j + 1);
66+
printf("}");
67+
}
68+
printf("\n");
69+
return 0;
70+
}
71+
72+
//C(字典顺序)
73+
#include <stdio.h>
74+
#include <stdlib.h>
75+
#define MAXSIZE 20
76+
int main(void) {
77+
int set[MAXSIZE];
78+
int i, n, position = 0;
79+
printf("输入集合个数:");
80+
scanf("%d", &n);
81+
printf("\n{}");
82+
set[position] = 1;
83+
while(1) {
84+
printf("\n{%d", set[0]); // 印第一个数
85+
for(i = 1; i <= position; i++)
86+
printf(",%d", set[i]);
87+
printf("}");
88+
if(set[position] < n) { // 递增集合个数
89+
set[position+1] = set[position] + 1;
90+
position++;
91+
}
92+
else if(position != 0) { // 如果不是第一个位置
93+
position--; // 倒退
94+
set[position]++; // 下一个集合尾数
95+
}
96+
else // 已倒退至第一个位置
97+
break;
98+
}
99+
printf("\n");
100+
return 0;
101+
}

八枚银币/八枚银币.c

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
八枚银币
3+
*/
4+
5+
#include <stdio.h>
6+
#include <stdlib.h>
7+
#include <time.h>
8+
void compare(int[], int, int, int);
9+
void eightcoins(int[]);
10+
int main(void) {
11+
int coins[8] = {0};
12+
int i;
13+
srand(time(NULL));
14+
for(i = 0; i < 8; i++)
15+
coins[i] = 10;
16+
printf("\n输入假币重量(比10大或小):");
17+
scanf("%d", &i);
18+
coins[rand() % 8] = i;
19+
eightcoins(coins);
20+
printf("\n\n列出所有钱币重量:");
21+
for(i = 0; i < 8; i++)
22+
printf("%d ", coins[i]);
23+
printf("\n");
24+
return 0;
25+
}
26+
void compare(int coins[], int i, int j, int k) {
27+
if(coins[i] > coins[k])
28+
printf("\n假币%d 较重", i+1);
29+
else
30+
printf("\n假币%d 较轻", j+1);
31+
}
32+
void eightcoins(int coins[]) {
33+
if(coins[0]+coins[1]+coins[2] ==
34+
coins[3]+coins[4]+coins[5]) {
35+
if(coins[6] > coins[7])
36+
compare(coins, 6, 7, 0);
37+
else
38+
compare(coins, 7, 6, 0);
39+
}
40+
else if(coins[0]+coins[1]+coins[2] >
41+
coins[3]+coins[4]+coins[5]) {
42+
if(coins[0]+coins[3] == coins[1]+coins[4])
43+
compare(coins, 2, 5, 0);
44+
else if(coins[0]+coins[3] > coins[1]+coins[4])
45+
compare(coins, 0, 4, 1);
46+
if(coins[0]+coins[3] < coins[1]+coins[4])
47+
compare(coins, 1, 3, 0);
48+
}
49+
else if(coins[0]+coins[1]+coins[2] <
50+
coins[3]+coins[4]+coins[5]) {
51+
if(coins[0]+coins[3] == coins[1]+coins[4])
52+
compare(coins, 5, 2, 0);
53+
else if(coins[0]+coins[3] > coins[1]+coins[4])
54+
compare(coins, 3, 1, 0);
55+
if(coins[0]+coins[3] < coins[1]+coins[4])
56+
compare(coins, 4, 0, 1);
57+
}
58+
}

八皇后/八皇后.c

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
八皇后
3+
*/
4+
#include <stdio.h>
5+
#include <stdlib.h>
6+
#define N 8
7+
int column[N+1]; // 同栏是否有皇后,1表示有
8+
int rup[2*N+1]; // 右上至左下是否有皇后
9+
int lup[2*N+1]; // 左上至右下是否有皇后
10+
int queen[N+1] = {0};
11+
int num; // 解答编号
12+
void backtrack(int); // 递回求解
13+
int main(void) {
14+
int i;
15+
num = 0;
16+
for(i = 1; i <= N; i++)
17+
column[i] = 1;
18+
for(i = 1; i <= 2*N; i++)
19+
rup[i] = lup[i] = 1;
20+
backtrack(1);
21+
return 0;
22+
}
23+
void showAnswer() {
24+
int x, y;
25+
printf("\n解答%d\n", ++num);
26+
for(y = 1; y <= N; y++) {
27+
for(x = 1; x <= N; x++) {
28+
if(queen[y] == x) {
29+
printf(" Q");
30+
}
31+
else {
32+
printf(" .");
33+
}
34+
}
35+
printf("\n");
36+
}
37+
}
38+
void backtrack(int i) {
39+
int j;
40+
if(i > N) {
41+
showAnswer();
42+
}
43+
else {
44+
for(j = 1; j <= N; j++) {
45+
if(column[j] == 1 &&
46+
rup[i+j] == 1 && lup[i-j+N] == 1) {
47+
queen[i] = j;
48+
column[j] = rup[i+j] = lup[i-j+N] = 0;
49+
backtrack(i+1);
50+
column[j] = rup[i+j] = lup[i-j+N] = 1;
51+
}
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)