百鸡问题的程序www.sng

Download Report

Transcript 百鸡问题的程序www.sng

C 语 言 教 程 _ 5
随机模拟
利用计算机语言提供的随机函数,计算机可以模拟一些随机事件
,用于科学试验、预测预算、计算机游戏等应用埸合。
(1)
C语言的伪随机数函数
rand(x);
rand()产生一个从0到32767之间的伪随机数。使用本函数应使用
#include <stdlib.h>。我们常常用(rand( )%N)这样的一个表达式来
产生一个从0~N-1之间的整数。(曾经说过%是求余运算符)
(2)随机数初始化函数
randomize();
用一个time不断变化的时间函数对随机数函数发生器进行初始化
。因此使用本函数应使用#include <time.h>。
www.sng-tc.ys168.com
常用rand()%N这样的一个表达式来产生一个从0~N-1之间的整数。
假
设我们希望产生一个在A到B之间的随机数(A<B),则我们可以这样写随机数生
成的式子:
x = rand()%(B-A+1)+A;
x = rand()% B+1
产生的随机数x是在0到B之间的整数;
x = rand()%(B-A+1)+A 产生的随机数x是在A到B之间的整数。
随机数生成举例:
(1) 产生1至6的随机整数r
r = rand() % 6 + 1;
(2) 产生2000至2050的随机整数r
r = rand()% 51 + 2000
[探索1] 请依据下面给出的条件写出随机数生成的式子。
(1) 产生100至999的随机整数r
_____________________________
(2) 产生10以内的随机奇数r
_____________________________
(3) 产生100以内被5整除的随机整数r
___________________________________
www.sng-tc.ys168.com
随机产生一道两位正整数的加法题
【例1】随机产生一道两位正整数的加法题。
#include <stdlib.h>
真正实现随机函数要包含这三个头文件。
#include<stdio.h>
#include <time.h>
这个语句保证了每次运行,产生的随机数都不同。如
main()
果去掉这句话,则每次都产生相同的整数序列。
请确保这句语句是在所有rand()前面,这样这句语句就
{
int a,b,c;
能对它之后的所有rand()函数发生作用。
randomize();
a=rand()%90+10;
b=rand()%90+10;
printf(“%d + %d = ”, a ,b );
scanf(“%d”,&c);
if ( a+b == c) printf(“ YES \n”);
else printf( “ NO “) ;
}
另一个随机数发生函数random(num);则产生一个从0到num-1的伪
随机正整数。
使用random函数例1中的a,b的随机数产生可更改为:
a = random(90)+10 ;
b = random(90)+10 ;
www.sng-tc.ys168.com
模拟七选三的彩票中奖机率
【例2】模拟七选三的彩票中奖机率
(1)先随机产生三个从1到7的数a,b,c为彩票中奖号码。
(2)再随机产生1000组选号x,y,z
(3)统计中奖的选号有多少。
#include<stdio.h>
#include <stdlib.h>
#include <time.h>
main()
{ int a,b,c,x,y,z,j,p=0 ;
clrscr(); randomize();
a=random(7)+1; b=random(7)+1; c=random(7)+1;
for (j=1; j<=1000; j++)
{ x=random(7)+1; y=random(7)+1; z=random(7)+1;
if ( x==a && y==b && z==c )
{
p++;
printf(“ ( %d ) %d %d %d \n”, p, x, y, z) ;
}
}
}
[探索2] 请多运行几遍,仔细看一下结果,有问题吗?可改进吗?
www.sng-tc.ys168.com
Break与continue语句
为了使循环控制更加灵活,C语言提供了break语句和continue
语句
1.一般格式: break;
continue;
2.功能
(1)break:强行结束循环,转向执行循环语句的下一条语句。
(2)continue:对于for循环,跳过循环体其余语句,转向循环变
量增量表达式的计算;对while和do-while循环,跳过循环体其余语
句,但转向循环继续条件的判定。
3.说明
(1)break能用于循环语句和switch语句中,continue只能用于循环
语句中。
(2)循环嵌套时,break和continue只影响包含它们的最内层循环
,与外层循环无关。
www.sng-tc.ys168.com
求1至100间的全部素数
【例1】求1至100间的全部素数。
#include<math.h>
/*数学函数包含*/
main()
{
int x,k,n=0;
for(x=1;x<=100; x=x+2)
{
k= sqrt(x) ; /*求平方根函数*/
for(n=2; n<=k ; n++)
if (x % n = = 0) break;
if ( n >= k+1)
printf( “ %d is a prime.\n ”, x ) ;
}
}
这里的break是当有一个被整除的数时,就可断定不是素数,直接
跳出n的循环。不再用下一个数试除了。
www.sng-tc.ys168.com
 质数又称素数。指在一个大于1的自然数中,除了1和此整数自身外,
不能被其他自然数整除的数。因为合数是由若干个质数相乘而得来的,
所以,没有质数就没有合数,由此可见素数在数论中有着很重要的地
位。比1大但不是素数的数称为合数。1和0既非素数也非合数。质数
是与合数相对立的两个概念,二者构成了数论当中最基础的定义之一。
 只有1和它本身两个正因数的自然数,叫质数(Prime Number)。
(如:由2÷1=2,2÷2=1,可知2的因数只有1和它本身2这两个
约数,所以2就是质数。与之相对立的是合数:“除了1和它本身两
个因数外,还有其它因数的数,叫合数。”如:4÷1=4,4÷2=2,
4÷4=1,很显然,4的因数除了1和它本身4这两个因数以外,还有
因数2,所以4是合数。)
 100以内的质数有2,3,5,7,11,13,17,19,23,29,
31,37,41,43,47,53,59,61,67,71,73,79,
83,89,97,在100内共有25个质数。
www.sng-tc.ys168.com
找出车牌号
【例2】 一辆违规汽车逃离现埸,三位行人中,甲记得车牌号前二位数是
相同的,乙记得后二位数也是相同的。丙则记得这四个数字恰好是一个数
的平方数。编程找出车牌号。
#include <stdio.h>
#include <math.h>
main()
{ int a,b,c,x,y;
clrscr();
for(a=1;a<=9;a++)
for(b=0;b<=9;b++)
sqrt(x)是求平方根的函数,
{ x=a*1000+a*100+b*10+b; 因而要加#include <math.h> 数学库
y= sqrt (x);
if (x!=y*y) continue;
printf("x=%d",x); break;
}
}
而这个程序中的continue是在判别x不是一个平方数时,跳过下面的语
句,而继续下一个循环。这里使用continue并不像上一例中使用break跳出
当前的循环,而只是跳过了continue后的语句。
www.sng-tc.ys168.com
百鸡问题的程序
一起来看看,下面这个解答百鸡问题的程序
[百鸡问题]:一百元钱买一百只鸡。公鸡5元一只、母鸡3元一只、小
鸡一元钱买三只。问如何卖?
main()
{ int x,y,z ;
设公鸡买x只、母鸡买y只、小鸡买z只
for (x=0 ;x<=20 ; x++)
for (y=0 ; y<=33 ; y++)
{ z= 100 - x - y ;
if ( 5*x + 3*y + z/3 = = 100 )
printf( “ x=%d y=%d z=%d \n”,x,y,z);
}
}
[探索3] 请指出上面程序中隐藏的错误,可以试着运行一下,认真仔
细地看一下每一个结果,有什么问题吗?你可以从前面的举例中找改
进的答案吗?
www.sng-tc.ys168.com
百鸡问题的程序
前面解百鸡问题的程序中,z设定为整型变量,因而在循环中会遇到
不能被3整除的z。要避免这种情况,就可用到采用下面的方法。
main()
{
int x,y,z ;
设公鸡买x只、母鸡买y只、小鸡买z只
for (x=0 ;x<=20 ; x++)
当前买公鸡与母鸡的钱己超
for (y=0 ; y<=33 ; y++)
过100元所以跳出y循环。
{ if(5*x+3*y>100) break;
z = 100 - x - y ;
当前的z不能被3整除就跳过
if(z % 3 != 0) continue ;
下面的语句再做下一轮循环
if(5*x + 3*y + z/3 = =100)
printf( “ x=%d y=%d z=%d \n”,x,y,z);
}
}
[探索4] 请再从另一方面想想,前面是从鸡的只数上循环去找答案,那是
否可以从买鸡的钱数上循环去找答案呢?设买公鸡、母鸡与小鸡的钱数分
别为a元b元与c元,再尝试一下,可以编写出另一种解答的程序。
www.sng-tc.ys168.com
练习题-5
[c501] 随机产生两位正整数的减法题.要求大数减小数,共做十题,每题做对加
十分.最后给出总分
[c502] 请用两重循环编写一个程序,要求如下:
一百匹马驮一百担货,大马一匹驮三担,中马一匹驮二担,小马二匹驮一担。
问如何分配这一百担货?
[c503]有蜘蛛、蜻蜓、蝉共18只,总共有腿118条,有翅膀20对(蜘蛛8条腿;
蜻蜓6条腿,2对翅膀;蝉6条腿,1对翅膀) 。问蜘蛛、蜻蜓、蝉各有多少只?
[c504] 请编写一个程序,要求如下:
将三位正整数中所有的回文数全部显示出来。一个数若顺读与逆读都相同的称
回文数。如101、111、121等。
* (你能否使用两种不同的方法来编写这一程序?)
*[c505] 在五世纪末南北朝的张丘建在他的《张丘建算经》中有这样一道等差
数题: 今有某君以钱赠给许多人,第一人给三钱,第二人给四钱,继续依次递增,
钱给了其他许多人,再把所给的钱全部收回再平均分派,结果每人得一百钱。问人
数多少?
www.sng-tc.ys168.com
自学指导_5
while形式的循环语句
循环结构是程序中一种很重要的结构。其特点是, 在给定条件成立时,反复执
行某程序段,直到条件不成立为止。 给定的条件称为循环条件,反复执行的程序段
称为循环体。C语言提供了多种循环语句,可以组成各种不同形式的循环结构。
while语句
while语句的一般形式为:
while(表达式)语句; 其中表达式是循环条件,语句为循环体。
while语句的语义是:计算表达式的值,当值为真(非0)时, 执行循环体语句。
例如 统计从键盘输入一行字符的个数。
main()
{ int n=0;
printf("input a string:\n");
while(getchar()!='\n') n++;
printf("%d",n);
}
本例程序中的循环条件为getchar()!='\n',其意义是, 只要从键盘输入的字符
不是回车就继续循环。循环体n++完成对输入字符个数计数。从而程序实现了对输入
一行字符的字符个数计数。
www.sng-tc.ys168.com
自学指导_5
while形式的循环语句
使用while语句应注意以下几点:
1.while语句中的表达式一般是关系表达或逻辑表达式,只要表达式的值为真(非0)即可继续循环。
main()
{ int a=0,n;
printf(“\n input n: ”); scanf(“%d”,&n);
while ( n - -)
printf(“%d ”,a++*2);
}
本例程序将执行n次循环,每执行一次,n值减1。循环体输出表达式a++*2的值。该表达式等效于
(a*2;a++)
2.循环体如包括有一个以上的语句,则必须用{}括起来, 组成复合语句。
3.应注意循环条件的选择以避免死循环。
main(){
int a,n=0;
while(a=5)
printf(“%d ”,n++);
}
本例中while语句的循环条件为赋值表达式a=5, 因此该表达式的值永远为真,而循环体中又没
有其它中止循环的手段, 因此该循环将无休止地进行下去,形成死循环。
4.允许while语句的循环体又是while语句,从而形成双重循环。
www.sng-tc.ys168.com
自学指导_5
while形式的循环语句
do-while语句的一般形式为:
do
语句;
while(表达式);
其中语句是循环体,表达式是循环条件。
do-while语句的语义是:
先执行循环体语句一次,再判别表达式的值,若为真(非0)则继续循环,否则终止循环。
do-while语句和while语句的区别在于do-while是先执行后判断,因此do-while至少要
执行一次循环体。而while是先判断后执行,如果条件不满足,则一次循环体语句也不
执行。
while语句和do-while语句一般都可以相互改写。
void main(){
int a=0,n;
printf(“\n input n: ”);
scanf(“%d”,&n);
do printf(“%d ”,a++*2);
while (--n);
}
本例中,循环条件改为--n,否则将多执行一次循环。这是由于先执行后判断而造成的。
www.sng-tc.ys168.com
自学指导_5
while形式的循环语句
对于do-while语句还应注意以下几点:
1.在if语句,while语句中, 表达式后面都不能加分号, 而在 do-while语句的
表达式后面则必须加分号。
2.do-while语句也可以组成多重循环,而且也可以和while语句相互嵌套。
3.在do和while之间的循环体由多个语句组成时,也必须用{ }括起来组成一个复
合语句。
4.do-while和while语句相互替换时,要注意修改循环控制条件。
www.sng-tc.ys168.com