51、两个小程序

     最近看中期试卷,有两个题目,感觉不错,实现了一下,以自娱。

1、设一个环上有编号为 0~n-1 的 n 粒不同颜色的珠子 ( 每粒珠子颜色用字母表示,n 粒珠子的颜色由输入的字符串表示)。将环中某两粒珠子间剪开,环上珠子形成一个序列,然后按以下规则从序列中取走珠子:首先从序列左端取走所有连续同包珠子;然后从序列右端在剩下珠子中取走所有连续同色珠子,两者之和为该剪开处可取走珠子的粒数。在不同位置剪开,能取走的珠子数不尽相同。

      本程序所求的是在环上哪个位置剪开,按上述规则可取走的珠子粒数最多。程序中用数组存储字符串。例如,10 粒珠子颜色对应字符串为“aaabbbadcc”,从 0 号珠子前剪开,序列为 aaabbbadcc,从左端取走 3 粒 a 色珠子,从右端取走 2 粒 c 色珠子,共取走 5 粒珠子。若在 3 号珠子前剪开,即 bbbadccaaa 共可取走 6 粒珠子。

#include "iostream"

#include "string"

using namespace std;

int count(char *s,int start,int end)

{

int i,c=0,step=(start>end)?-1:1;

char color=s[start];

for(i=start;s[i]==color;i+=step)

  {

   if((step>0&&i>end)||step<0&&i<end) break;

   c++;

  }//for

return c;

}

int main()

{

char t,s[120];

int i,j,c,len,maxc,cut=0;

cout<<"input a string\n";

cin>>s;

len=strlen(s);

for(i=maxc=0;i<len;i++)

  {

   c=count(s,0,len-1);

   if(c<len) c+=count(s,len-1,0);

   if(c>maxc) 

   {

    cut=i;

    maxc=c;

   }//if

   t=s[0];

   for(j=1;j<len;j++) 

    s[j-1]=s[j];

    s[len-1]=t;

  }//for

cout<<"cut: maxc:"<<cut<<" "<<maxc;

return 1; 

}

2、递推法是利用问题本身所具有的一种递推关系求问题解的一种方法。设要求问题规模为N的解,当N=1时,解或为已知,或能非常方便地得到解。能采用递推法构造算法的问题有重要的递推性质,即当得到问题规模为i-1的解后,由问题的递推性质,能从已求得的规模为1,2,…,i-1的一系列解,构造出问题规模为i的解。这样,程序可从i=0或i=1出发,重复地,由已知至i-1规模的解,通过递推,获得规模为i的解,直至得到规模为N的解。

【问题】阶乘计算

问题描述:编写程序,对给定的n(n≦100),计算并输出k的阶乘k!(k=1,2,…,n)的全部有效数字。

    由于要求的整数可能大大超出一般整数的位数,程序用一维数组存储长整数,存储长整数数组的每个元素只存储长整数的一位数字。如有m位成整数N用数组a[ ]存储:

    N=a[m]×10m-1+a[m-1]×10m-2+ … +a[2]×101+a[1]×100

并用a[0]存储长整数N的位数m,即a[0]=m。按上述约定,数组的每个元素存储k的阶乘k!的一位数字,并从低位到高位依次存于数组的第二个元素、第三个元素……。例如,5!=120,在数组中的存储形式为:

3   0   2   1   ……

    首元素3表示长整数是一个3位数,接着是低位到高位依次是0、2、1,表示成整数120。

    计算阶乘k!可采用对已求得的阶乘(k-1)!连续累加k-1次后求得。例如,已知4!=24,计算5!,可对原来的24累加4次24后得到120。

    在本程序另外用变量c来表示位数,而用a[0]开始放置数据。

#include "iostream"

#include "string"

using namespace std;

const int MAXN=1000;

int a[MAXN],b[MAXN];

void pnext(int k,int &c)//c is the number of (k-1)!

{//c是(k-1)!的位数

int i,m,r;

for(i=0;i<c;i++)

 b[i]=a[i];

a[c]=0;

for(m=1;m<k;m++) //累加k次(k-1)!的数值,实际在原来的基础上加(k-1)次

 for(i=0;i<c;i++)

 {

 r=a[i]+b[i];

 a[i]=r%10;

 a[i+1]+=r/10;

 }//for

 //处理符号位

 r=a[c];

 while(r>0)//看是否最高位有进位

 {

 a[c++]=r%10;

 r=r/10;

 }

}

void write(int *a,int k,int c)

{

int i;

cout<<k<<"!=";

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

 cout<<a[i];

cout<<endl;

}

int main()

{

int n,c,k;

cout<<"ENter a a number n(n<100):";

cin>>n;

a[0]=1;

c=1;

write(a,1,c);

for(k=2;k<=n;k++)

  {

   pnext(k,c);

   write(a,k,c);

  }

return 1;

}

注:此题目也可按照大数相乘的方法来做,即将每一个数(相乘的两个数)都存取一个字符数组中去。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值