- 浏览: 1409845 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
sdgxxtc:
[quo[color=red]te][/color]
C#使用OleDb读取Excel,生成SQL语句 -
zcs302567601:
博主,你好,一直都有个问题没有搞明白,就是 2.x的版本是通过 ...
NGUI所见即所得之UIPanel -
一样的追寻:
感谢楼主!
有向强连通和网络流大讲堂——史无前例求解最大流(最小割)、最小费用最大流 -
cp1993518:
感谢!从你的博客里学到了很多
Unity日志工具——封装,跳转 -
cp1993518:
学习了~,话说现在的版本custom还真的变委托了
NGUI所见即所得之UIGrid & UITable
C语言名题精选百则——数字问题
这篇博文,D.S.Qiu将对《C语言名题精选百则》第二章进行整理推出,本章一共16个问题,不光只是书上的名题,还会依据互联网的资源进行不断补充,加强(由于匆忙,暂时还只是罗列的过程,不过很快就有深度的发掘)。如果你有建议、批评或补充,请你不吝提出(email:gd.s.qiu@gmail.com,或者直接在本文末评论)。你的支持和鼓励,我将渐行渐远!
这篇博文整理的太艰难了,其中一度想放弃,个人觉得难度有点大,如果没有需求驱动的话,很难读下去,但最终为了保持文章的完整性,还是硬着头皮去截图整理。这16个问题主要经常的是对质数的求解,因式分解,整数自乘(快速求解),Fibonacci数(快速求解),二项式求解(快速求解),阶乘(快速求解),这些都是数论或者组合数学的基本内容,但要通过计算机基本求解的算法赴复杂度过高,文中给出了相应的快速算法,对有需求的读者来说,还是可以喜出望外的(也只是大概的理解了下),应该还有更多精彩的求解方法(日后定当补充)。终于写完了,没有你的支持和鼓励,很难继续下去,下一篇是《排列,组合与集合》。
问题2.1 Armstrong 数(ARMS1.C,ARMS2.C )
在三位的正整数中,例如abc,有一些可以满足a³+b³+c³ = abc的条件,也就是说, 各个位数的立方和正好是该数的本身,这些数称为Armstrong数。试编写一个程序来求出
所有的三位Armstrong数。
【说明】
这是个常见的问题,许多课本、习题集都有。解决的基本方法就在于有没有办法从一 个三位数中把它的3个位数取出(例如,把379分解成3、7与9),或者在已知3个位数 时把该三位数算出来(例如,已知百位为5,十位为1,个位为9,则三位数为519)。
另一个变形是给出一个数,证明它是否为一个Armstromg数。这两者类似,由自己产 生的数可以永远控制在三位,但是后者却一定要去测试它是不是三位数。
如何测试一个数是否为三位数呢?有的书中介绍这样一种方法(见程序UGLY.C), 使用对数log()以及指数exp()函数,不仅如此,还要用四舍五入(在C语言中只好加上 0.5再转型成整数)。为什么?原来只是在取出输入数据的某一个位数而已。一个简单的 程序写得如此复杂,大多数初学者恐怕都很难看明白。在此给出一个提示,千万不要重蹈覆辙。
(1)如果要确认x是个五位数,就看x/100000是否为零。如果为零,那么x的位数 不会超过五位。接着再检查x是否真的是五位,这就要看:
(x % 100000)/10000
是否为零,如果不为零,这个值就是x中从右向左数第五位数的值;如果是零,x就最多只能有四位而已。为什么?因为x%100000是把x用100000去除的余数,值在0〜99999 之间,正是x的右边五位,再用10000去除,那就是第五位的值了;如果x是五位数,那么这个位数就一定大于1,如程序2-1所示。
【程序】
程序2-1(UGLY.C)
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> void main(void) { int number; /* the input number */ int pos, ten_pow; /* # of digits and 10^x */ int arm_no; /* computed Armstrong Number*/ int temp, i; /* working variables */ float expon; /* computed exponent */ char line[100]; /* input buffer */ printf("\nPlease key in number : "); /* get a number*/ gets(line); number = atoi(line); pos = 0; /* count # of digits */ ten_pow = 1; /* power of 10, 10^0=1 */ do { /* start counting */ ten_pow *= 10; /* one more digit... */ pos++; } while (ten_pow < number); if (ten_pow == number) /* all 10^x are not Arm # */ printf("\n%d is not an Armstrong Number.", number); else { /* not 10^x */ ten_pow = number; /* now ten_pow is a temp var*/ arm_no = 0; /* initial value for Arm. # */ for (i = pos-1; i >= 1; i--) { /* scan from R->L*/ expon = exp(i*log(10.0)); /* the ugly part */ temp = ten_pow / expon; /* you do it... */ ten_pow %= (int)(expon + 0.5); arm_no += exp(pos*log(temp)) + 0.5; } arm_no += exp(pos*log(ten_pow)) + 0.5; if (arm_no == number) printf("\n%d is an Armstrong Number.", number); else printf("\n%d is not an Armstrong Number.", number); } }
(2)如果这两个条件都正确,则x是一个五位数。
(3)按照这个技巧,要找出x的第三位(自右往左算),那就是
(x%1000)/100
(4)用下面的式子也可以求出x的第三位的值:
(x/100)%10
问题实现
/* ------------------------------------------------------ */ /* PROGRAM Armstrong Number Search : */ /* This program searches all 3-digit Armstrong Numbers */ /* and thus numbers in the range of 0-99 are not counted. */ /* */ /* Copyright Ching-Kuang Shene June/29/1989 */ /* ------------------------------------------------------ */ #include <stdio.h> void main(void) { int p, q, r; /* three digits */ int p_cube, q_cube, r_cube; /* their cubes */ int p100, q10; /* their position values */ int number; /* the computed number */ int cube_sum; /* the sum of the cubes */ int count = 0; /* counter */ printf("\nArmstrong Number Search"); printf("\n======================="); printf("\n\nCount Number"); printf( "\n----- ------"); for (p = 1, p100 = 100; p <= 9; p++, p100+=100) { p_cube = p*p*p; for (q = q10 = 0; q <= 9; q++, q10+=10) { q_cube = q*q*q; for (r = 0; r <= 9; r++) { r_cube = r*r*r; number = p100 + q10 + r; cube_sum = p_cube + q_cube + r_cube; if (number == cube_sum) printf("\n%3d%9d", ++count, number); } } } printf("\n\nThere are %d 3-digit Armstrong Numbers.", count); }
问题2.2数字谜(TRENTE.C )
在一些游戏与休闲的书刊中,经常会看到如下的数字谜
试编写一个程序进行破解(看下面的规则说明)。
【说明】
数字谜的规则是这样的:
(1)不同的英文字母表示不同的数字。因此,题目中最右边一行的T、Q、E就是不同的数。
(2)每一个数最左边一位不是0。所以上面的谜题中,V、C、T都不是0。
(3)上面的题目是加,那就表示VINGT这个五位数与CINQ这个四位数的两倍相加 后,会得到TRENTE这个六位数,并且数字的安排如谜语所示。
在解这些数字谜时,很多人都会不知不觉地用最笨拙的方法,因此可能执行好几分钟, 甚至好几小时都得不到结果。就以上题为例,它一共有9个不同的字母,因此耗用10个数 字符号中的9个,很多人就会写出下面的形式,如程序2-2所示。
【程序】
程序2-2
for(v=1;v<=9;v++)
for(I=0;I<=9;I++)
……
for(E=0;E<=9;E++)
{
VINGT=……;
CINQ=……;
TRENTE=……;
if(TRENTE == VINGT + CINQ +CINQ)
{
……
}
}
如果用这个程序,那么也许一两个小时也不一定能够算出结果,因为在最内层循环中 的if 一共要执行将近10^9,近一亿次,所以这是最笨的方法。通常,用一点小学算术知识就可以节省大量的计算时间。换言之,可以用四则运算来 找出某个字母值的范围(如偶数、奇数、5〜9、3或4等,而不是0〜9),范围越小,程序的工作就越少,执行起来就越快。
不妨从这一点出发,就本题而给出一些提示:
(1)因为3个位数相加,最大就是9+9+9=27,如果从这一个位数的右边一位会有进 位,那么这个进位就最多是2,所以3个位数再加上进位的最大值是29,所以该位数和是 9,而进位是2。
(2)现在看V那位,加上进位之后得到TR,因为V最大是9,进位最大是2,所以 TR的最大值是11。因为T是结果的第一位,所以不能是0,因此只好是1;但结果前两位 是TR, TR最大是11,现在T是1,于是R只能是0。注意,如果R是2〜9中任意一个, 那就表示没有从R到T的进位,因而T就是0 了。所以从一点看来,两个值就固定了,即T=1, R=0。
(3)再来看V,V—定大于8。为什么?千位数的进位最大是2,要一个数加上2而 有两位数,那么这个数不就至少是8吗?
(4)看个位数的E。它是由T加上两个Q得来的,已知T是1,而2Q—定是偶数, 所以E是个奇数。
就用这4点提示,T与R的循环就不必了; E的循环有3、5、7、9 (注意,T是1, E 就不能用1); V的循环只能用8与9。还没有决定的就剩下I、N、G、C与Q5个,所以循 环就有7层,I、N、G与Q为0〜9; C为2〜9 (因为C是第一位,不能是0,也不能是1, 因为T是1),E是3、5、7、9; V是8与9,所以最内层的if就执行了 10^4x7x4x2次而已,于是用这个方法写成的程序所花的时间大约是前面所提到的:
10^4x7x4x2/10^9=0.056%
因此可以看到节省了多少时间。
思考一下,另外是否还有其他可以节省时间的方法呢?
问题实现
/* ------------------------------------------------------ */ /* PROGRAM Number Puzzle : */ /* This is first solution of the number puzzle. It is */ /* written under the guidelines in my book. For each */ /* digit, there corresponds a for loop and an if statement*/ /* to prevent duplicated digits. Read it carefully. */ /* */ /* Copyright Ching-Kuang Shene June/30/1989 */ /* ------------------------------------------------------ */ #include <stdio.h> void main(void) { long I, N, R=0, E, V, G, C, Q, T=1; long IN, VINGT, CINQ, TRENTE; long sum; printf("\nNumber Puzzle\n"); printf("\n VINGT"); printf("\n CINQ"); printf("\n+) CINQ"); printf("\n--------"); printf("\n TRENTE\n"); for (V=8; V<=9; V++) for (I=0; I<=9; I++) if (I != V && I!=T) for (N=0; N<=9; N++) if (N!=I && N!=V && N!=T) { IN = I*10 + N; for (G=0; G<=9; G++) if (G!=N && G!=I && G!=V && G!=T && G!=R) for (C=2; C<=9; C++) if (C!=G && C!=N && C!=I && C!= V && C!=T && C!=R) for (Q=2; Q<=9; Q++) if (Q!=C && Q!=G && Q!=N && Q!=I && Q!=V && Q!=T && Q!=R) for (E=3; E<=9; E+=2) if (E!=Q && E!=C && E!=G && E!=N && E!=I && E!=V && E!=T && E!=R) { TRENTE=((((T*10+R)*10+E)*10+N)*10+T)*10+E; VINGT=((V*100+IN)*10+G)*10+T; CINQ =(C*100+IN)*10+Q; sum=VINGT+CINQ+CINQ; if (sum==TRENTE) { printf("\n\nThe answer is :\n"); printf("\n%8ld", VINGT); printf("\n%8ld", CINQ); printf("\n+)%6ld", CINQ); printf("\n--------"); printf("\n%8ld", TRENTE); } } } }
问题2.3求质数(PRIME1.C )
试编写一个程序,找出前N (如200)个质数。如果没有进一步要求,这不是难题。 但在此希望从所知的、使用除法的方法中,用最快的办法来编写程序。
【说明】
可能最先想到的办法,就是让某个变量i从2变到N,然后检查它是不是质数,如果是就显示出来,如果不是,就检查下一个。这是正确的做法,但却没有注意到一个小细节, 因而使程序运行速度变慢。当然,2是质数,但所有2的倍数都不是质数,如果令i从2 变到N,不就很冤枉地测试了 4,6,8,10,…这些数?所以第一点提示是测试2,3,5,7,…,N,即 2与所有奇数就足够了。同理,3是质数,但6,9,12,…这些3的倍数却不是,因此,如果能够把2与3的倍数都跳过去而不测试,任意连续的6个数中,就只会测试两个而已。以6n,6n+1,6n+2,6n+3,6n+4,6n+5 为例,6n,6n+2,6n+4 是偶数,又 6n+3 是 3 的倍数,所以如果 把2与3的倍数都不理会,要测试的数就只留下6n+1与6n+5而已,因而工作量只是前述想法的2/6=1/3,应该用这个方法去编写程序。
/* ------------------------------------------------------ */ /* PROGRAM prime number generator : */ /* This program generates first MAXSIZE-1 primes by */ /* using the conventional division method, but multiples */ /* of 2 and 3 are not tested. Therefore it is faster. */ /* */ /* Copyright Ching-Kuang Shene July/02/1989 */ /* ------------------------------------------------------ */ #include <stdio.h> #define MAXSIZE 100 #define YES 1 #define NO 0 void main(void) { int prime[MAXSIZE]; /* array to contains primes */ int gap = 2; /* increasing gap = 2 and 4 */ int count = 3; /* no. of primes */ int may_be_prime = 5; /* working variable */ int i, is_prime; prime[0] = 2; /* Note that 2, 3 and 5 are */ prime[1] = 3; /* primes. */ prime[2] = 5; while (count < MAXSIZE) { /* loop until prime[] full*/ may_be_prime += gap; /* get next number */ gap = 6 - gap; /* switch to next gap */ is_prime = YES; /* suppose it were a prime*/ for (i = 2; prime[i]*prime[i] <= may_be_prime && is_prime; i++) if (may_be_prime % prime[i] == 0) /* NO */ is_prime = NO; /* exit */ if (is_prime) /* if it IS a prime... */ prime[count++] = may_be_prime; /* save it */ } printf("\nPrime Number Generation Program"); printf("\n===============================\n"); printf("\nFirst %d Prime Numbers are :\n", count); for (i = 0; i < count; i++) { if (i % 10 == 0) printf("\n"); printf("%5d", prime[i]); } }
/* ------------------------------------------------------ */ /* FUNCTION sieve : */ /* This program uses Eratosthenes Sieve method to */ /* generate all primes between 2 and MAXSIZE*2+3. This */ /* is a very simple yet elegant method to generate primes */ /* */ /* Copyright Ching-Kuang Shene July/01/1989 */ /* ------------------------------------------------------ */ #include <stdio.h> #define MAXSIZE 200 #define DELETED 1 #define KEPT 0 void main(void) { int sieve[MAXSIZE+1]; /* the sieve array */ int count = 1; /* no. of primes counter */ int prime; /* a generated prime */ int i, k; /* working variable */ printf("\nEratosthenes Sieve Method"); printf("\n========================="); printf("\n\nPrime Numbers between 2 and %d\n", MAXSIZE*2+3); for (i = 0; i <= MAXSIZE; i++) /* set all items to be*/ sieve[i] = KEPT; /* kept in the sieve */ for (i = 0; i <= MAXSIZE; i++) /* for each i, it */ if (sieve[i] == KEPT) { /* corresponds to 2i+3*/ prime = i + i + 3; /* if it is not sieved*/ count++; /* prime=2i+3. */ for (k = prime + i; k <= MAXSIZE; k += prime) sieve[k] = DELETED; /* screen multiple*/ } printf("\n%6d", 2); /* output part. */ for (i = 0, k = 2; i <= MAXSIZE; i++) if (sieve[i] == KEPT) { if (k > 10) { printf("\n"); k = 1; } printf("%6d", 2*i+3); k++; } printf("\n\nThere are %d primes in total.", count); }
/* ------------------------------------------------------ */ /* PROGRAM linear sieve program of Gries and Misra : */ /* This program finds all prime numbers between 2 and */ /* n, the input, by using Gries and Misra linear sieve */ /* method. This method does not use division, instead */ /* multiplications are used. */ /* */ /* Copyright Ching-Kuang Shene July/10/1989 */ /* ------------------------------------------------------ */ #include <stdio.h> #include <stdlib.h> #define MAXSIZE 1000 #define NEXT(x) x = next[x] #define REMOVE(x) { next[previous[x]] = next[x]; \ previous[next[x]] = previous[x]; \ } #define INITIAL(n) { unsigned long i; \ for (i = 2; i <= n; i++) \ previous[i] = i-1, next[i] = i+1;\ previous[2] = next[n] = NULL; \ } void main(void) { unsigned long previous[MAXSIZE+1]; /* prev. pointer */ unsigned long next[MAXSIZE+1]; /* next pointer */ unsigned long prime, fact, i, mult; unsigned long n; unsigned long count = 0; char line[100], dummy; printf("\nLinear Sieve Program"); printf("\n===================="); printf("\n\nPrime Numbers between 2 to --> "); gets(line); n = strtoul(line, &dummy, 10); INITIAL(n); /* initial the set */ for (prime = 2; prime*prime <= n; NEXT(prime)) for (fact = prime; prime*fact <= n; NEXT(fact)) for (mult = prime*fact; mult <= n; mult *= prime) REMOVE(mult); /* remove multiples */ for (i = 2; i != NULL; NEXT(i)) { /* display result */ if (count % 8 == 0) printf("\n"); printf("%6ld", i); count++; } printf("\n\nThere are %ld Prime Numbers in Total", count); }
/* ------------------------------------------------------ */ /* PROGRAM factorization of positive integers : */ /* Given un unsigned long integer, this program finds */ /* all prime factor by using traditional division method. */ /* */ /* Copyright Ching-Kuang Shene July/10/1989 */ /* ------------------------------------------------------ */ #include <stdio.h> #include <stdlib.h> #define MAXSIZE 100 #define SAVE_FACTOR(fact, exp) { if (exp > 0) \ factors[count] = fact, \ exps[count++] = i; \ } void main(void) { unsigned long factors[MAXSIZE]; /* stores factors */ unsigned long exps[MAXSIZE]; /* stores exps */ unsigned long n, work; int count = 0; /* factor counter */ int i, k; char line[100], *dummy; printf("\nFactorization by Division Program"); printf("\n================================="); printf("\n\nInput a positive integer --> "); gets(line); n = strtoul(line, &dummy, 10); for (i=0,work=n; (work & 0x01UL)==0 && work>1; work>>=1,i++) ; /* extract divisor 2 */ SAVE_FACTOR(2, i); /* save it and its exp. */ for (k = 3; k <= work; k += 2) { /* for k=3,5,7,9,.. */ for (i = 0; work % k == 0 && work > 1; work /= k, i++) ; /* extract divisor k */ SAVE_FACTOR(k, i); /* save it and its exp. */ } printf("\n%ld = ", n); /* display result. */ for (i = 0; i < count; i++) printf("%ld(%ld)", factors[i], exps[i]); }
unsigned long recursive_power(unsigned long m, unsigned long n) { unsigned long temp; if (n == 0) /* m^0 = 1 */ return 1; else if (n & 0x01UL == 0) { /* if power is even then */ temp = recursive_power(m, n >> 1); return temp * temp; /* m^(2k) = (m^k)^2 */ } else /* otherwise, m^n=m*m^(n-1) */ return m * recursive_power(m, n-1); }
unsigned long iterative_power(unsigned long m, unsigned long n) { unsigned long temp = 1; while (n > 0) { /* if there exists 1 bits.. */ if (n & 0x01UL == 1)/* the right most one ? */ temp *= m; /* YES, the result get a 'm'*/ m *= m; /* anyway, compute m^k */ n >>= 1; /* throw away this bit */ } return temp; }
unsigned long fibonacci(int n) { unsigned long f0, f1, temp; int i; if (n <= 2) return 1; else { for (f0 = f1 = 1, i = 3; i <= n; i++) { temp = f0 + f1; /* temp = f(n-2)+f(n-1) */ f0 = f1; /* f0 = f(n-2) */ f1 = temp; /* f1 = f(n-1) */ } return f1; } }
可以用这个观点来编写程序。
- void matrix_power(unsigned long, unsigned long,
- unsigned long, unsigned long, int,
- unsigned long *, unsigned long *,
- unsigned long *, unsigned long *);
- unsigned long fibonacci(int n)
- {
- unsigned long a, b, c, d;
- if (n <= 2)
- return 1;
- else { /* A^(n-2) of a matrix A */
- matrix_power(1UL, 1UL, 1UL, 0UL, n-2, &a, &b, &c, &d);
- return a + b;
- }
- }
- /* ------------------------------------------------------ */
- /* FUNCTION matrix_power : */
- /* This function accepts a matrix X and computes */
- /* X^(n-2) for n >= 3 using the power computation method, */
- /* where X is defined as follows */
- /* */
- /* +- -+ +- -+(n-2) */
- /* | aa bb | | a b | */
- /* | | = | | */
- /* | cc dd | | c d | */
- /* +- -+ +- -+ */
- /* ------------------------------------------------------ */
- void matrix_power(unsigned long a, unsigned long b,
- unsigned long c, unsigned long d, int n,
- unsigned long *aa, unsigned long *bb,
- unsigned long *cc, unsigned long *dd)
- {
- unsigned long xa, xb, xc, xd;
- if (n == 1)
- *aa = a, *bb = b, *cc = c, *dd = d;
- else if (n & 0x01 == 1) { /* n odd: X^(2k+1)=X*X^(2k)*/
- matrix_power(a, b, c, d, n-1, &xa, &xb, &xc, &xd);
- *aa = a*xa + b*xc;
- *bb = a*xb + b*xd;
- *cc = c*xa + d*xc;
- *dd = c*xb + d*xd;
- }
- else { /* n even: X^(2k)=(X^(2k))^2*/
- matrix_power(a, b, c, d, n>>1, &xa, &xb, &xc, &xd);
- *aa = xa*xa + xb*xc;
- *bb = xa*xb + xb*xd;
- *cc = xc*xa + xd*xc;
- *dd = xc*xb + xd*xd;
- }
- }
- /* ------------------------------------------------------ */
- #include <stdio.h>
- #include <stdlib.h> /* for function atoi() */
- void main(void)
- {
- char line[100];
- int n;
- printf("\nO(log(n)) Fibonacci Number Computation\n");
- printf("\nn please ---> ");
- gets(line);
- n = atoi(line);
- printf("\nfib(%d) = %lu", n, fibonacci(n));
- }
- unsigned long ext_fibonacci(int n, int x, int y)
- {
- unsigned long f0, f1;
- unsigned long a0, a1;
- unsigned long temp1, temp2;
- int i;
- if (n == 0)
- return 1;
- else if (n == 1)
- return 2;
- else {
- for (f0 = f1 = 1, a0 = 1, a1 = 2, i = 2; i <= n; i++) {
- temp1 = x*f1 + y*f0;
- f0 = f1;
- f1 = temp1;
- temp2 = x*a0 + y*(a1 - f0) + f0 + f1;
- a0 = a1;
- a1 = temp2;
- }
- return a1;
- }
- }
- /* ------------------------------------------------------ */
- #include <stdio.h>
- #include <stdlib.h>
- void main(void)
- {
- char line[100];
- int n, x, y;
- printf("\nExtended Fibonacci Number Computation\n");
- printf("\nGiven x and y, define the Extended Fibonacci"
- " Number as follows\n");
- printf("\nXfib(0) = 1; Xfib(1) = 1;"
- " Xfib(n) = x*Xfib(n-1) + y*Xfib(n-2)\n");
- printf("\nNow given another integer n, compute the sum of");
- printf("\nXfib(0)*Xfib(n) + Xfib(1)*Xfib(n-1) + ... +"
- " Xfib(i)*Xfib(n-i) + ... ");
- printf("\n + Xfib(n-1)*Xfib(1) + Xfib(n)*Xfib(0)\n");
- printf("\nx ---> ");
- gets(line);
- x = atoi(line);
- printf("\ny ---> ");
- gets(line);
- y = atoi(line);
- printf("\nn ---> ");
- gets(line);
- n = atoi(line);
- printf("\n\nAnswer is %lu", ext_fibonacci(n, x, y));
- }
- #define MAXSIZE 100
- unsigned long cnr(int n, int r)
- {
- unsigned long c[MAXSIZE];
- int i, j;
- for (i = 0; i <= r; i++) /* initial c[] to all 1's */
- c[i] = 1UL;
- for (i = 1; i <= n-r; i++) /* compute C(n,r) by add. */
- for (j = 1; j <= r; j++) /* but compute only */
- c[j] += c[j-1]; /* those needed. */
- return c[r];
- }
/* --------------------------------------------------------- */ /* FUNCTION cnr : */ /* A special function to calculate all C(n,r)'s given n. */ /* It employs a very special trick on bit operations. NOTE */ /* that depend on the number of bits for unsigned long type */ /* this function might returns wrong answer. The rule of */ /* thumb is that if unsigned long has k bits then the max. */ /* of n, the input, should be no more than following : */ /* */ /* -1 + sqrt(1 + 4*k) */ /* -------------------- */ /* 2 */ /* */ /* Thus for k=32 as many microprocessor has, then the max. */ /* of n is 5. But this should not be viewd as a restriction */ /* because the same algorithm can be used in more advanced */ /* non-numeric applications. */ /* */ /* Copyright Ching-Kuang SHENE Feb/24/1989 */ /* --------------------------------------------------------- */ unsigned long power(unsigned long, unsigned long); void cnr(int n, int answer[]) { unsigned long x = (1 << n) + 1; /* 2^n + 1 */ unsigned long mask = (1 << n) - 1; /* 2^n - 1, n 1's */ unsigned long result; int i; result = power(x, (unsigned long) n); /* (2^n+1)^n */ for (i = 0; i <= n; i++, result >>= n) /* retrieve data */ answer[i] = result & mask; } /* ------------------------------------------------------ */ /* FUNCTION power : */ /* This is the function called 'iterative_power' in */ /* file I_POWER.C of this book. */ /* ------------------------------------------------------ */ unsigned long power(unsigned long m, unsigned long n) { unsigned long temp = 1; while (n > 0) { /* if there exists 1 bits.. */ if (n & 0x01UL == 1)/* the right most one ? */ temp *= m; /* YES, the result get a 'm'*/ m *= m; /* anyway, compute m^k */ n >>= 1; /* throw away this bit */ } return temp; } /* ------------------------------------------------------ */ #include <stdio.h> #include <stdlib.h> #define MAXSIZE 10 void main(void) { int answer[MAXSIZE]; int n, r; char line[100]; printf("\nFast Combinatorial Coefficient Computation"); printf("\n=========================================="); printf("\n\nN ---> "); gets(line); n = atoi(line); cnr(n, answer); printf("\nAll Combinatorial Coefficients :\n"); for (r = 0; r <= n; r++) printf("\nC(%d,%d) = %d", n, r, answer[r]); }
- unsigned long power(unsigned long, unsigned long);
- void cnr(int n, int answer[])
- {
- unsigned long x = (1 << n) + 1; /* 2^n + 1 */
- unsigned long mask = (1 << n) - 1; /* 2^n - 1, n 1's */
- unsigned long result;
- int i;
- result = power(x, (unsigned long) n); /* (2^n+1)^n */
- for (i = 0; i <= n; i++, result >>= n) /* retrieve data */
- answer[i] = result & mask;
- }
- /* ------------------------------------------------------ */
- /* FUNCTION power : */
- /* This is the function called 'iterative_power' in */
- /* file I_POWER.C of this book. */
- /* ------------------------------------------------------ */
- unsigned long power(unsigned long m, unsigned long n)
- {
- unsigned long temp = 1;
- while (n > 0) { /* if there exists 1 bits.. */
- if (n & 0x01UL == 1)/* the right most one ? */
- temp *= m; /* YES, the result get a 'm'*/
- m *= m; /* anyway, compute m^k */
- n >>= 1; /* throw away this bit */
- }
- return temp;
- }
- /* ------------------------------------------------------ */
- #include <stdio.h>
- #include <stdlib.h>
- #define MAXSIZE 10
- void main(void)
- {
- int answer[MAXSIZE];
- int n, r;
- char line[100];
- printf("\nFast Combinatorial Coefficient Computation");
- printf("\n==========================================");
- printf("\n\nN ---> ");
- gets(line);
- n = atoi(line);
- cnr(n, answer);
- printf("\nAll Combinatorial Coefficients :\n");
- for (r = 0; r <= n; r++)
- printf("\nC(%d,%d) = %d", n, r, answer[r]);
- }
- unsigned long mask; /* mask for shifting bits */
- unsigned cnrs[100]; /* storage for C(n,n/2)'s */
- int number; /* index for cnrs[] */
- int p_size; /* partition size in C(n,n/2) */
- unsigned long factor(unsigned long);
- unsigned long power(unsigned long, unsigned long);
- /* -------------------------------------------------------- */
- /* FUNCTION factorial : */
- /* Control routine of n! calculation. */
- /* -------------------------------------------------------- */
- unsigned long factorial(unsigned long n)
- {
- unsigned long x = (1 << n) + 1;
- number = 0; /* set index to init. pos. */
- mask = (1 << n) - 1; /* set up mask for shifting */
- p_size = n; /* set up partition size */
- (void) power(x, n); /* now computing (2^n+1)^n */
- number = 0; /* reset index to the start */
- return factor(n); /* then compute n! */
- }
- /* -------------------------------------------------------- */
- /* FUNCTION factor : */
- /* This is the working routine for n!. The idea is */
- /* */
- /* +- 1 if n = 1 */
- /* | */
- /* n! = + n * (n-1)! if n is odd */
- /* | */
- /* +- C(n,n/2)*[(n/2)]! if n is even */
- /* */
- /* Before factor() is called n_power() is used to compute */
- /* (2^n+1)^n and during the course of this computation, it */
- /* stores all relevant C(n,n/2) into array cnrs[]. Thus */
- /* C(n,n/2)'s are available from array C(n,n/2) here. */
- /* -------------------------------------------------------- */
- unsigned long factor(unsigned long n)
- {
- unsigned long temp;
- if (n == 1)
- return 1;
- else if (n & 0x01UL == 1)
- return n * factor(n - 1);
- else {
- temp = factor(n >> 1);
- return cnrs[number++] * temp * temp;
- }
- }
- /* -------------------------------------------------------- */
- /* FUNCTION power : */
- /* The modified power function to compute (2^n+1)^n in */
- /* recursive mode. During its computation, n_power() will */
- /* save C(n,n/2) into array cnrs[]. */
- /* -------------------------------------------------------- */
- unsigned long power(unsigned long n, unsigned long m)
- {
- unsigned long temp;
- if (m == 1)
- temp = n;
- else if (m & 0x01UL != 0)
- temp = n * power(n, m-1);
- else {
- temp = power(n, m >> 1);
- temp *= temp;
- cnrs[number++] = (temp >> ((m >> 1)*p_size)) & mask;
- }
- return temp;
- }
- /* -------------------------------------------------------- */
- #include <stdio.h>
- #include <stdlib.h> /* for strtoul() function */
- void main(void)
- {
- char line[100], *dummy_ptr;
- unsigned long m, n;
- printf("\nThe Fast N! Computation :");
- printf("\n\nN for N! please --> ");
- gets(line);
- n = strtoul(line, &dummy_ptr, 10);
- printf("\n%lu! = %lu", n, factorial(n));
- }
- #include <stdio.h>
- #include <stdlib.h>
- void main(void)
- {
- long left, right; /* left and right bound */
- long sum; /* computed sum */
- long GIVEN; /* the given number */
- int count = 0; /* solution counter */
- char line[100]; /* input buffer */
- printf("\nConsecutive sum to a fixed given number");
- printf("\n=======================================\n");
- printf("\nYour number (> 0) please ---> ");
- gets(line);
- GIVEN = atol(line);
- for (sum = 0, right = 1; sum < GIVEN; sum += right, right++)
- ;
- for (left = 1, right--; left <= GIVEN/2; )
- if (sum > GIVEN) /* if sum too large */
- sum -= (left++); /* reduce from left */
- else {
- if (sum == GIVEN) { /* if equal, print it */
- printf("\n%ld = sum from %ld to %ld",
- GIVEN, left, right);
- count++; /* and increase count */
- } /* if sum too small */
- sum += (++right); /* increase from right */
- }
- if (count > 0)
- printf("\n\nThere are %d solutions in total.", count);
- else
- printf("\n\nSorry, there is NO solution at all.");
- }
发表评论
-
C#使用OleDb读取Excel,生成SQL语句
2013-06-27 15:47 10075C#使用OleDb读取Excel,生成SQL语句 ... -
C#读写XML文件工具类——满足一切需求
2013-06-18 07:33 10781C#读写XML文件工具类— ... -
C#解析XML
2013-06-17 19:20 0覆盖 -
C#读取Excel数据动态生成对象并进行序列化
2013-06-16 20:10 8007C#读取Excel数据 ... -
Unity导入unitypackage总是失败问题原因
2013-06-11 22:54 11486最近尝试手游开发,用的Unity引擎,然后开 ... -
C# socket连接服务器发送和接收数据在设置断点单步执行没有问题但是直接运行不能成功
2013-06-04 20:26 5977题目有点长, ... -
C# 调用Delegate.CreateDelegate方法出现“未处理ArgumentException”错误解决
2013-05-31 12:24 3569在C# 调用Delegate.Create ... -
考题小记(希望能持续增加)
2013-04-03 16:11 0在一块黑板上将123456789重复50次得到450位数12 ... -
数组问题集结号
2012-12-06 22:01 0数组是最简单的数据结构,数组问题作为公司招聘的笔试和面试题目 ... -
算法问题分析笔记
2012-12-05 11:59 01.Crash Balloon Zhejiang Univer ... -
Java文件输出时,文件大小只有24KB
2012-11-14 22:10 1661今天,用Java做点事情,出现了一个很莫名其妙的事情就是文件 ... -
C语言名题精选百则——终曲
2012-11-05 23:27 50第9章终 曲 W 闼题9.1等璗正负号段 ... -
C语言名题精选百则——游戏问题
2012-11-05 23:27 86第8章游戏问题 问题8.1苞数阶魔方阵(MAGIC_O ... -
C语言名题精选百则——序曲
2012-11-04 23:27 2379C语言名题精选百则——序曲 ... -
C语言名题精选百则——排序
2012-11-04 23:29 128第5章排 序 问题5.1 二分插入法(BIN ... -
C语言名题精选百则——查找
2012-11-04 23:29 4140尊重他人的劳动,支持原创 本篇博文,D.S.Q ... -
C语言名题精选百则——排列,组合与集合
2012-11-04 23:28 10837C语言名题精选百则—— ... -
C语言名题精选百则——数字问题
2012-11-04 23:23 0C语言名题精选百则 ... -
C语言名题精选百则——序曲
2012-11-04 23:02 2C语言名题精选百则—— ... -
大数据、海量数据处理之偷星摘月
2012-10-25 14:45 0第一部分、十道海量数据处理面试题 1、海量日志数据,提 ...
相关推荐
除了上述的基础类别之外,《C语言名题精选百则 技巧篇》还包含了一类特别的题目——小游戏程序。这类题目虽然看似简单,却能有效地帮助学习者将编程知识应用于实际的项目中。通过编写猜数字游戏、井字游戏等简单文字...
以下是对【C语言精选一百题】中四个代表性题目的深入解析,通过这些题目的实践,我们可以体会C语言处理问题的多样性和灵活性。 首先,我们来解析【程序 1】。该题目的主旨是探讨数字组合问题,具体为在1、2、3、4四...
实验——任意精度算数(Calc)就是这样一个例子,它展示了如何用C语言构建一个能执行任意精度算术运算的库。 任意精度算术的实现通常涉及以下几个关键点: 1. **数据结构**:大数通常用数组或者链表存储,每个元素...
在C语言编程中,"数字棋"通常是指一种基于数字的棋类游戏,可能是通过控制台实现的。这种游戏可能涉及到逻辑判断、循环结构、条件语句等C语言基础概念。下面将详细介绍C语言编程中的一些关键知识点,以及如何利用...
综上所述,C语言编程题精选分析提供了多种类型的问题场景,让学习者能够在实践中掌握C语言的基础知识和应用技巧。通过对这些精选题目的深入分析和解答,不仅能够巩固C语言的理论知识,还能提升解决实际问题的能力。...
【C语言编写抢三十游戏——源码.pdf】文档是一个关于使用C语言编写的抢三十游戏的源代码示例。这个游戏的目标是玩家与电脑之间通过轮流选择1到3的数字,第一个使得总和达到30的人获胜。以下是源码中涉及的关键知识点...
《单片机C语言程序设计实训100例——基于8051+Proteus仿真》是一本针对初学者和进阶者深入学习单片机编程的实用教材。本书的核心在于通过100个实际的C语言编程实例,帮助读者掌握8051系列单片机的使用技巧,同时结合...
《C语言课程设计——猜数字游戏》 猜数字游戏是一种简单而有趣的计算机程序,它通常由计算机随机生成一个数字,然后让玩家尝试猜测这个数字。在这个C语言课程设计项目中,我们将探讨如何利用C语言的基本语法和逻辑...
基于给定文件的信息,我们可以深入探讨“C语言毕业设计——敢死队问题”这一主题,主要聚焦于如何使用C语言解决约瑟夫环问题,并利用循环链表作为数据结构来实现算法。 ### 重要概念与知识点 #### 1. 约瑟夫环问题...
《单片机C语言程序设计实训100例——基于8051+Proteus仿真》案例压缩包,这是一份专为学习单片机C语言编程的实践教程,涵盖了丰富的实例,旨在帮助初学者深入理解单片机的工作原理和编程技巧。8051单片机是经典且...
《C语言接口与实现》是一本深入探讨C语言编程技术的经典著作,旨在提供对C语言内部机制的透彻理解。该书的一个实验部分是关于多精度算术(MPCalc),这是一种实现大整数计算的方法,它允许进行超越标准整型范围的...
根据给定文件的信息,我们可以提炼出五个与C语言相关的编程问题及解答,下面将逐一进行详细解析。 ### 1. 输出所有不同的三位数 题目要求输出所有不同的三位数(即三位数字互不相同)。该程序通过三层循环遍历1到4...
标题中的“2021-11-22 C语言学习应用——用C语言实现大数相乘(csdn)————程序.pdf”指的是一个关于C语言编程的学习资料,特别是讲解如何使用C语言来处理大数相乘的问题。描述中提到的“2021-11-22 C语言学习...
《C语言经典例题解析——助你开启编程之旅》 ...每一道题都是一次动手实践的机会,每解决一个问题,都是对C语言理解的加深。只有理论与实践相结合,才能真正掌握C语言,为未来更深入的编程学习打下坚实基础。
《C语言编程实践指南——基于链表、矩阵与管理系统的深度探索》 C语言作为基础且广泛应用的编程语言,是每一位计算机科学初学者的必修课。本资料集"**C语言练习题含答案.rar**"针对大一学生设计,旨在帮助初学者...
C语言的json解析工具——cJSON是一个轻量级的库,专为在C语言环境中解析和生成JSON(JavaScript Object Notation)数据而设计。JSON是一种常见的数据交换格式,广泛应用于Web服务和应用程序之间的数据传输。cJSON库...
【水费问题——C语言代码】是一个针对初学者的编程作业,主要涉及C语言的基础语法和逻辑控制。在这个问题中,编程者需要实现一个程序,该程序能够计算和处理水费的相关计算。C语言是一种静态类型、编译式的程序设计...
单片机C语言程序设计实训100例是学习单片机编程的重要资源,尤其对于初学者来说,通过实例操作可以更好地理解和掌握单片机的工作原理及编程技巧。本实训教程专注于8051系列单片机,这是一种广泛应用的8位微处理器,...
当我们在C语言中声明一个变量时,系统会根据数据类型的大小在内存中划分出相应大小的空间,并为这个空间赋予一个名称,也就是我们所使用的变量名。例如,当我们声明一个整型变量`int i;`时,系统就会为变量`i`分配两...
在IT领域,神经网络是一种模仿人脑神经元结构的计算模型,用于解决复杂的学习和识别问题。LeNet-5是Yann LeCun在1998年提出的一个经典卷积神经网络(Convolutional Neural Network,CNN)架构,主要用于手写数字识别...