您的位置:首页 > 其它

<<离散数学>>for其实可以非常酷

2016-06-08 20:06 423 查看
1 计算机如何完成多个数相加

2 计算机如何完成通过加法来算乘法

3 标准输入输出流

4 计算机如何完成阶乘

5 计算一个数的颠倒数

6 计算一个数组n的k组合,也就是等于计算一个集合的所有子集,计算一个数组n的k组合排列,也就是要计算一个集合的所有子集的排列,0-K-n。

某人购买的体育彩票猜中了4个号码,这4个号码按照从大到小的顺序组成一个数字可被11整除,将其颠倒过来也可被11整除,编写函数求符合这样条件的4个号码。可被11整除颠倒过来也可被11整除的正整数例如341,它可被11整除,颠倒过来143也可被11整除。体育彩票采用整数1、2、3、……、36表示36种体育运动。

代码采用穷举,非常的罗嗦,虽然是我自己写的,但是依然要批评。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>

typedef struct databox {
int datasun[8];
int *ponit;
}ps;
int dataint(int *num);
void DataSum(int n);
long JC(int n);
int NI(int sum);
void DataMinus(int n1, int n2, int n3, int n4);
void CP(ps *p);
void Pintobox(int i, ps *box);
void clear(ps *box);
int Mult10(int n);
int main()
{
ps box,*pbox;
pbox = &box;
DataSum(199999990);
DataMinus(3, 4, 5, 6);
int c=NI(1234);
clear(pbox);
CP(pbox);

}
//1.计算数的阶乘
long JC(int n) {
int nn = n;
long sel=1;
while (nn != 1) {
sel = sel*nn;
nn--;
}
return sel;
}
//2.把一个数组的数串,变一个整数,去掉多余的0
int dataint(int *num) {
int sum=0;
int st=0;

for (int j = 7; j >= 0; j--)
{
int zz = *(num + j);

if (zz!=-1) {
int ww = Mult10(st);
int ee = zz*ww;
sum=sum + ee;
st = st + 1;
}
}
//printf("%d", sum);
return sum;

}
//3.计算10的n次方
int Mult10(int n)
{
int sum = 10;
int m;
if (n == 0) return 1;
for (m = 1; m<n; m++) sum *= 10;
return sum;
}
//4.计算一个数的颠倒数
int NI(int i) {
int  j = 0, sum = 0;
int a, y, p, st = 0, m;
int num[10] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
a = i;
p = (int)pow(10, 1);
while (a >= p) {
y = a%p;
if (y != 0) {
num[j++] = y;
}
a = a / p;
}
num[j] = a;
m = j + 1;
sum=dataint(num);
return sum;
}
//5.计算一个数列的乘积
void DataMinus(int n1, int n2, int n3, int n4)
{
int s = 0;
for (int i = 1; i < n1; i++)
for (int i = 1; i < n2 ; i++)
for (int i = 1; i < n3; i++)
for (int i = 1; i < n4; i++)
s = s + 1;
//printf("3*4*5*6=%d\n", s);
}
//6.计算数列1----n的和
void DataSum(int n) {
int k = 0;
for (int i = 1; i < n; i = i + 1)
k = k + i;
printf("1+2+3+...%d,the result is %d\n",n,k);
}
//7.把一串数字单个放入数组中
void Pintobox(int i,ps *box) {
int st = 0;
int k = i / 10;
int w = i % 10;
if (k != 0)
{
*((*box).ponit) = k;
(*box).ponit++;
*((*box).ponit) = w;
(*box).ponit++;
}
else
{
*((*box).ponit) = w;
(*box).ponit++;
}

}
//8.求组合并且分析数字是否被11整除
void CP(ps *box) {
int data[15] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
long J4;
long P4;
int sun;
int J1, J3, J2, J5, J6;
int total = 0;
//计算一个数组的组合有哪些
for (int *Ja = &data[0]; Ja <= &data[14]; Ja++) {
for (int *Jb = &data[0]; Jb <= &data[14]; Jb++) {
for (int *Jc = &data[0]; Jc <= &data[14] && Jb != Ja; Jc++) {
for (int *Jd = &data[0]; Jd <= &data[14] && Jc != Ja&&Jc != Jb; Jd++) {
if (Jd != Ja&&Jd != Jb&&Jd != Jc) {
//printf("a=%d\tb=%d\tc=%d\td=%d\n", *Ja, *Jb, *Jc, *Jd);
total = total + 1;
Pintobox(*Ja, box);
Pintobox(*Jb, box);
Pintobox(*Jc, box);
Pintobox(*Jd, box);
sun = dataint((int *)box);
clear(box);
//printf("sun is %d\t", sun);

int sunni = NI(sun);
//printf("ni is %d\n", sunni);

if (sunni % 11 == 0 && sun%11 == 0) {
printf("\t%d is a good number\n", sun);
}
//else {
//  printf("%d is not a good number\n", sun);
//}
}
}
}
}
}
printf("total is%d\n", total);
//计算一个数的组合中,选4个的组合有多少种
J1 = JC(1);
J2 = JC(2);
J3 = JC(3);
J6 = JC(6);
J5 = JC(32);
printf("j1=%d\tj2=%d\tj3=%d\tj5=%d\tj6=%d\n", J1, J2, J3, J5, J6);
J4 = JC(15) / (JC(4)*JC(15 - 4));
printf("C(14,4)=%d\n", J4);
//计算一个数的排列中,选4个的组合有多少种
P4 = JC(15) / JC(15 - 4);
printf("P(14,4)=%d\n", P4);
}
//9.清除数组元素的值
void clear(ps *box) {
ps *head = box;
(*box).ponit =(int*) box;
for (int i = 0; i < 8; i++) {
*((*box).ponit) = -1;
(*box).ponit++;

}
(*box).ponit = &(*head).datasun[0];

}


对于允许重复的排列,十分简单;就是n*n*n*n*n…

对于不允许重复的排列,可以用一连串for循环来表示

int k = 0;
for (int i1 = 1; i1 < 8; i1++)
for (int i2 = 1; i2 < 8; i2++)
for (int i3 = 1; i3 < 8&&i2!=i1; i3++)
for (int i4 = 1; i4 <8&&i3!=i2&&i3!=i1; i4++)
for (int i5 = 1; i5 < 8 && i4 != i3&&i4 != i2&&i4 != i1; i5++) {
if (i5 != i4&&i5 != i3&&i5 != i2&&i5 != i1) {
printf("%d", i1);
printf("%d", i2);
printf("%d", i3);
printf("%d", i4);
printf("%d", i5);
k = k + 1;
printf("\n");
}
}
printf("%d", k);
printf("%d", 49 * 49 * 7);


for的这种结构,类似于一连串正方形,从大到小依次排列,正方形就是一个循环,如果条件不成立,正方形底部中间会发出一条out线,直接连接到上一个正方形状的右边,再进行循环。类似一笔画,可以有很多的中间正方形,也可以重复的画某一个正方形,关键在于条件你怎么设置。

例如,我们在求组合的时候,1-7按照从大到小顺序排列,求出组合数目,不重复。

int k = 0;
for (int i1 = 1; i1 < 8; i1++)
for (int i2 = 1; i2 < i1; i2++)
for (int i3 = 1; i3 < i2 ; i3++)
for (int i4 = 1; i4 <i3; i4++)
for (int i5 = 1; i5 < i4; i5++) {
printf("%d", i1);
printf("%d", i2);
printf("%d", i3);
printf("%d", i4);
printf("%d", i5);
k = k + 1;
printf("\n");
}

printf("%d", k);
printf("%d", 3* 7);


例如,我们在求组合的时候,1-7按照从大到小顺序排列,求出组合数目,可以重复。

int k = 0;
for (int i1 = 1; i1 <8; i1++)
for (int i2 = 1; i2 <=i1; i2++)
for (int i3 = 1; i3 <=i2 ; i3++)
for (int i4 = 1; i4 <=i3; i4++)
for (int i5 = 1; i5 <=i4; i5++) {
printf("%d", i1);
printf("%d", i2);
printf("%d", i3);
printf("%d", i4);
printf("%d", i5);
k = k + 1;
printf("\n");
}

printf("%d", k);
printf("%d", 42* 11);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: