GameMaker游戏编程 GM算法(2)_简单数值算法

GameMaker游戏编程 GM算法(2)_简单数值算法

首页角色扮演超变GM更新时间:2024-09-04

产生11个随机不重复的1到100的数

产生11个随机不重复的1到100的数

create;

a[10]=0

for (i=0; i<=10; i =1)

{

do

{

a[i]=ceil(random(100));

flag=0

for (j=0; j<i; j =1)

{

if(a[i]==a[j]){flag=1;}

}

}

until (flag==0);

}

draw:

for (i=0; i<=10; i =1)

{

draw_text(100,20*i,a[i]);

}

1*2*3*4*5*…*100

Create:

sum=1

for(i=2;i<=100;i =1)

{

sum=sum*i

}

show_message(sum)

求s=a aa aaa aaaa aa...a的值

题目:求s=a aa aaa aaaa aa...a的值,其中a是一个数字。

例如2 22 222 2222 22222(此时共有5个数相加)

create:

n=get_integer("输入项数:",5);

s=2;

sum=0;

for (i=1; i<=n; i =1)

{

sum =s;

s=s*10 2

}

show_message(sum)

求1 2! 3! ... 20!

求1 2! 3! ... 20!的和。

分析:此程序只是把累加变成了累乘。

create:

sum=0;

a=1;

for (i=1; i<=3; i =1)

{

a*=i

sum =a;

}

show_message(sum)

求 2/1 3/2 5/3 8/5...

有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和。

分析:请抓住分子与分母的变化规律。

create:

main()

a=2;

b=1;

sum=0;

for (i=1; i<=20; i =1)

{

sum =a/b;

temp=a;

a=a b

b=temp;

}

show_message(sum)

小球反弹多高

一球从100米高度自由落下,每次落地后反跳回原高度的一半,再落下。求它在第10次落地时,共经过多少米?第10次反弹多高?

create:

h=100;

sum=100;

for (i=2; i<=10; i =1) //第一次的直接加了,从第二次算起!自己画图就明白了。

{

h=h/2;

sum =2*h;

}

show_message(sum)

数组逆序输出

将一个数组逆序输出。

分析:用第一个与最后一个交换。

create:

for (i=0; i<=5; i =1){ a[i]=i }

N=i-1;

for (j=0; j<=N div 2; j =1)

{

temp=a[N-j];a[N-j]=a[j];a[j]=temp

}

draw:

for (j=0; j<=N; j =1)

{

draw_text(100,20*j,a[j])

绘制国际象棋棋盘

要求输出国际象棋棋盘。

分析:用i控制行,j来控制列,根据i j的和的变化来控制输出黑方格,还是白方格。

draw:

for (i=0; i<8; i =1)

{

for (j=0; j<8; j =1)

{

if ((i j) mod 2 ==0)

{

draw_text(j*50,i*50,"hei");

}

else

{

draw_text(j*50,i*50,"bai");

}

}

}

水仙花数

打印出100到1000所有的“水仙花数”,所谓“水仙花数”是指一个三位数,其各位数字立方和等于该数 本身。例如:153是一个“水仙花数”,因为153=1的三次方+5的三次方+3的三次方。

分析:利用for循环控制100-999个数,每个数分解出个位,十位,百位。

draw:

bai=0

shi=0

ge=0

lie=0

for (i=100; i<1000; i =1)

{

bai =i div 100;

shi =i div 10 mod 10;

ge = i mod 10;

if (bai*100 shi*10 ge==power(bai,3) power(shi,3) power(ge,3))

{

draw_text(10,30*lie,i);

lie =1;

}

}

回文数

一个5位数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同。

create:

a=get_integer("输入一个五位数:",12321)

wan=a div 10000;

qian=a div 1000 mod 10;

shi=a div 10 mod 10;

ge=a mod 10;

if (wan==ge && qian==shi)

{

show_message("是回文数");

}

else

{

show_message("不是回文数");

}

完全平方数

一个整数,它加上100后是一个完全平方数,再加上268又是一个完全平方数,请问该数是多少?

分析:在10万以内判断,先将该数加上100后再开方,再将该数加上268后再开方,如果开方后的结果没有小数部分说明能开方尽,即为平方数。请看具体分析:

create:

for (i=0; i<100000; i =1)

{

xx=frac(sqrt(i 100)); //xx为加上100后开方后的结果的小数部分

yy=frac(sqrt(i 268)); //yy为再加上268后开方后的结果的小数部分

if (xx==0 && yy==0) //小数部分为0,说明能开方尽,即为平方数

{

show_message("该数为:" string(i));

}

}

判断素数

判断101-200之间有多少个素数,并输出所有素数。

分析:判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除,则表明此数不是素数,反之是素数。

draw:

hang=0;

flag=0;

k=1

sushu=0

for (i=101; i<200; i =1)

{

for (j=2; j<=sqrt(i); j =1)

{

if(i mod j == 0){ flag=0; break; }

}

if(flag==1){draw_text(10,20*k,i);k =1;sushu =1}

flag=1

}

draw_text(10,20*k,"su shu gong you:" string(sushu) "ge")

分解质因数

将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5。

create:

n=get_integer("输入一个数:",90);

s="1";

for (i=2; i<=n; i =1)

{

while (n mod i == 0)

{

s ="*" string(i);

n=n/i;

}

}

draw:

draw_text(100,100,s);

完数

一个数如果恰好等于它的因子之和,这个数就称为“完数”。例如6=1+2+3。

Create:

n=get_integer("输入一个数:",6);

s_y=n;

s=0;

for (i=2; i<=n; i =1)

{

while (n mod i == 0)

{

s =i;

n=n/i;

}

}

if (s_y == s 1)

{

show_message("是完数");

}

else

{

show_message("不是完数");

猴子分桃

题目:海滩上有一堆桃子,五只猴子来分。第一只猴子把这堆桃子平均分为五份,多了一个,这只猴子把多的一个扔入海中,拿走了一份。第二只猴子把剩下的桃子又平均分成五份,又多了一个,它同样把多的一个扔入海中,拿走了一份,第三、第四、第五只猴子都是这样做的,问海滩上原来最少有多少个桃子?

设A、B、C、D、E五只猴子,最后E猴扔掉一只桃子后分成5份,每份是x只桃子,则共有:{《[(5x 1)×5/4 1] ×5/4 1》×5/4 1}×5/4 1只桃子。

提示:设第四只猴子分时总桃子为y个,则丢掉一个并带走自己的那份1/5后剩下4/5的为:(y-1)*4/5,第四只剩下的和第五只猴子开始分的桃子数应该相等,于是:(y-1)*4/5 = 5x 1 ,于是第四只猴子分时总桃子为y,y=(5x 1)*5/4 1,后面的依此类推,得到:{《[(5x 1)×5/4 1] ×5/4 1》×5/4 1}×5/4 1 =(3125/256)(x 1)-4;

又因为:(3125/256)(x 1)为正整数,x 1=256,∴min x=255,(3125/256)(x 1)-4=3125-4=3121;

于是想到了枚举法

Create:

tao_num = 0

for (i=6; i<10000; i =1)

{

tao_num = i

for (j=1; j<=5; j =1)

{

tao_num = tao_num*5/4 1;

}

if((tao_num-1) mod 5 == 0)

{

break

}

tao_num = 0

}

show_message(tao_num)

这一题和后面递推算法中的猴子吃桃问题不同!

日期天数计算

输入某年某月某日,判断这一天是这一年的第几天?

分析:以3月5日为例,应该先把前两个月的加起来,然后再加上5天即本年的第几天。特殊情况:是闰年且输入月份大于3时需考虑多加一天。

create:

year=0

month=0

day=0

sum=0

isleap=0

do

{

year=get_integer("输入年",2014);

}

until (frac(year)==0 && is_real(year));

do

{

month=get_integer("输入月",4);

}

until (frac(month)==0 && is_real(month) && month>0 && month<=12);

do

{

day=get_integer("输入日",3);

}

until (frac(day)==0 && is_real(day) && day>0 && day<=31);

mydatetime = date_create_datetime(year,month,day,0,0,0);

switch(month)//先计算某月以前月份的总天数

{

case 1:sum=0;break;

case 2:sum=31;break;

case 3:sum=59;break;

case 4:sum=90;break;

case 5:sum=120;break;

case 6:sum=151;break;

case 7:sum=181;break;

case 8:sum=212;break;

case 9:sum=243;break;

case 10:sum=273;break;

case 11:sum=304;break;

case 12:sum=334;break;

default:show_message("错误");

}

sum =day; //再加上某天的天数

if (date_leap_year(mydatetime) && month>2)

{

sum =1; //如果是闰年且月份大于2,总天数应该加一天

}

show_message(string(sum));

9*9乘法口诀

draw:

kongzhi=1

huitu=0

for (i=1; i<=9; i =1)

{

for (j=kongzhi; j<=9; j =1)

{

jieguo =i * j ;

draw_text(i*70,huitu*30,string(i) "*" string(j) "=" string(jieguo))

huitu =1 //绘图行位置控制

}

kongzhi =1 //i和j都为列,kongzhi使下一列的j值加一,看图就明白了!

huitu=0

}

最大公约数和最小公倍数

输入两个正整数m和n,求其最大公约数和最小公倍数。

程序分析:利用辗除法。

create:

a=get_integer("输入一个数:",4);

b=get_integer("输入一个数:",2);

n1=a;

n2=b;

if(a<b){tempt=a;a=b;b=tempt;}

while (b!=0)

{

r=a mod b;

a=b;

b=r;

}

show_message("最大公约数为:" string(a));

show_message("最小公倍数为:" string(n1*n2/a)); //a、b的最小公倍数为:a*b/最大公约数,自己举两个数就明白了。

看不懂的请看如下分析:

计算最大公因数的最简单方法(最小公倍数也可以用类似枚举法),但是效率较低(如果数字非常大,这种方法要循环很多次才能计算出来)。

Scripts:

//scr_maxgys(a,b)

{

var a=argument0

var b=argument1

var c = min(a,b)

for (i=c; i>=1; i-=1)

{

if(a mod i == 0 and b mod i == 0)

{

return i

}

}

}

Create:

show_message(scr_maxgys(40,80));

经典的计算两个正整数的最大公约数的算法是欧几里德算法,又称辗除法。其计算原理依赖于下面的定理(gcd(a,b) 表示 a, b 的最大公约数):

gcd(a,b) = gcd(b,a mod b) (a>b 且a mod b 不为0)

证明: a可以表示成a = kb r,则r = a mod b,假设d是a,b的一个公约数,则有d整除a, d整除b,而r = a - kb,因此d整除r,因此d也是(b,a mod b)的公约数,因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等,得证

根据这个算法编写代码,gcd(M,N) ,假设 M>=N (如果 N>M ,则循环的第一次迭代将它们互相交换)

设两数为a、b(a>b),求a和b最大公约数(a,b)的步骤如下:用a除以b,得a÷b=q......r1(0≤r1)。若r1=0,则(a,b)=b;若r1≠0,则再用b除以r1,得b÷r1=q......r2 (0≤r2).若r2=0,则(a,b)=r1,若r2≠0,则继续用r1除以r2,……如此下去,直到能整除为止。其最后一个为被除数的余数的除数即为(a, b)。

例如:a=25,b=15,a/b=1......10,b/10=1......5,10/5=2.......0,最后一个为被除数余数的除数就是5,5就是所求最大公约数。

辗转相除法基于如下原理:两个整数的最大公约数等于其中较小的数和两数的相除余数的最大公约数。

例如,252和105的最大公约数是21(252 = 21 × 12;105 = 21 × 5);

因为252 ÷105 = 2…42,所以(105,42)是21。在这个过程中,较大的数缩小了,所以继续进行同样的计算可以不断缩小这两个数直至余数变为零。这时的除数就是所求的两个数的最大公约数

辗转相除法基于如下原理:两个整数的最大公约数等于其中较小的数和两数的相除余数的最大公约数。

例如,252和105的最大公约数是21(252 = 21 × 12;105 = 21 × 5);

以252与105为例:

因为:

252 ÷105 = 2 … 42

252 = 2 * 105 42

252 - 2 * 105 = 42

252与105的最大公约数肯定能整除252与105,那也会整除252 - 2 * 105,即:252 - 2 * 105 = 42的等式左边能被最大公

约数整除,那么等式右边的42也会被最大公约数整除,即:252、105、42都能被最大公约数整除。

故,252和105的最大公约数,和105和42的最大公约数是一样的。

于是转化为求:105与42的最大公约了。

105 ÷ 42 = 2 … 21

42 ÷ 21 = 2 … 0

因为:余数为0,说明:21是105 与42的最大公约数,故也是252和105的最大公约数。

在这个过程中,较大的数缩小了,所以继续进行同样的计算可以不断缩小这两个数直至余数变为零。这时的除数就是所求的两个数的最大公约数

报3退出最后留下谁?

有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出 圈子,问最后留下的是原来第几号的那位。

create:

zren = get_integer("输入人数:",50); //总人数

shengxia=zren; //剩下的人数

jishu=0; //计数,三个数一轮回 1-2-3...

for (i=1; i<=zren; i =1) { ren[i]=i; }

while (shengxia>1)

{

for (i=1; i<=zren; i =1)

{

if (ren[i]!=0)

{

jishu =1;

if (jishu==3)

{

ren[i]=0;

jishu=0;

shengxia-=1;

}

}

}

}

for (i=1; i<=zren; i =1)

{

if(ren[i]!=0){show_message("最后剩下的是第" string(i) "个人")}

}

查看全文
大家还看了
也许喜欢
更多游戏

Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved