最近看中期试卷,有两个题目,感觉不错,实现了一下,以自娱。
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;
}
注:此题目也可按照大数相乘的方法来做,即将每一个数(相乘的两个数)都存取一个字符数组中去。