5.1.3 周期串
如果一个字符串可以由某个长度为k的字符串重复多次得到,我们说该串以为周期。例如,abcabcabcabc以3为周期(注意,它也以6和12为周期)。输入一个长度不超过80的串,输出它的最小周期。
样例输入:HoHoHo
样例输出:2
分析:方法1:
根据周期串的定义,假设周期串的长度mlen=1,2,3,4........len,len为输入串的长度,再定义一个临时数组model(与输入串一样的长度),把输入串中0--mlen之间的字符依次拷贝到model中,循环拷贝,直到model长度与输入串长度一致,strcmp()比较两个字符串。
代码:
#include "stdafx.h"
#include <iostream>
#include <string.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
char buf[101];
char model[101];
int i,j,mlen,len;
scanf("%s",buf);
len=strlen(buf);
for(mlen=1;mlen<=len;mlen++){
j=0;
for(i=0;i<len;i++){
model[j++]=buf[i%mlen];//buf[0]buf[1]...buf[len-1]buf[0]buf[1]...buf[len-1]...循环拷贝
//printf("%c\n",buf[i%mlen]);
}
model[j]='\0';//记得最后给字符串加上结束标志
cout<<model<<endl;
if(strcmp(buf,model)==0){//找到了
break;
}
}
printf("%d\n",mlen);
return 0;
}
方法2:假设周期串的长度mlen=1,2,3,4........len,len为输入串的长度,对输入串的每mlen个长度的子串进行比较。
代码:
#include "stdafx.h"
#include <iostream>
#include <string.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
char buf[101];
int i,j,mlen,len;
scanf("%s",buf);
len=strlen(buf);
for(mlen=1;mlen<=len;mlen++){
for(i=mlen,j=0;i<len;i++,j++){
if(buf[j%mlen]!=buf[i])
break;
}
cout<<i<<" "<<j<<endl;
if(i==len && (j%mlen==0)){//找到了
break;
}
}
printf("%d\n",mlen);
return 0;
}
5.2.1 小学生算术
在学习加法是时,发现“进位”特别容易出错。你的任务是计算两个整数在相加时需要多少次进位。你编制的程序应当可以连续处理多组数据,直到读到两个0(这是输入结束标记)。假设输入的整数都不超过9个数字。
样例输入:123 456
555 555
123 594
0 0
样例输出:0
3
1
分析:先假设我们用int存储输入,此题关键变成如何得到整数的个位,而同过取模的方法我们可以得到个位,且我们知道int的上限是2147483647,能存储10数,因此输入可用int保存。
代码:
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
int a,b;
int c,cnt;
int i;
while(scanf("%d%d",&a,&b)==2){
cnt=0,c=0;
if(!a && !b) break;//结束条件
int x,y;
for(i=0;i<=9;i++){
x=a%10;
a=a/10;
y=b%10;
b=b/10;
c= x+y>=10 ? 1:0;
if(c) cnt++;//效率更高的方法是cnt+=c;
}
printf("cnt=%d\n",cnt);
}
return 0;
}
5.4.2 因子和阶乘
输入正整数n(2≤n≤100),把阶乘n!=1×2×3ׄ×n分解成素因子相乘的形式,从
小到大输出各个素数(2、3、5、„)的指数。例如825=3×52
×11应表示成(0,1,2,0,1),表示分别有0、1、2、0、1个2、3、5、7、11。你的程序应忽略比最大素因子更大的素数(否则末尾会有无穷多个0)。
样例输入: 5 53
样例输出: 5!=3 1 1
53!=49 23 12 8 4 4 3 2 2 1 1 1 1 1 1 1
分析:算法框架
//n!的各个素因子的出现次数等于1-n中这些因子的素因子出现的次数的和
for(int i=2;i<=n;i++)
{
统计i的各个素数因子出现的次数
}
打印n!的各个素因子出现的次数</strong>
好了,现在问题转变为:如何求一个整数的各个素数因子出现的次数,算法框架如下:
1.求出1--x之间的所有素数,保存在数组primes中,用数组p存储各个素数出现的次数
2.for(int i=2;i<=x;i++){
int a=i;
for(int j=0;j<素数总数 && primes[j]<=a;){
if(a%/primes[j]==0){//能被第j个素数整除
++p[primes[j]];
a=a/primes[j];//统计有多少个primes[j]
}else j++;//统计下一个素数出现的次数
}
}
到此,所有问题都解决了,代码:
#include "stdafx.h"
#include<string.h>
int is_prime(int x)
{
if(x<2) return 0;
for(int i=2;i*i<=x;++i){
if(x%i==0) return 0;
}
return 1;
}
int primes[100],cnt,count[100];
int _tmain(int argc, _TCHAR* argv[])
{
int n;
while(scanf("%d",&n)==1){
memset(primes,0,sizeof(primes));
memset(count,0,sizeof(count));
cnt=0;
for(int i=2;i<=n;i++){
if(is_prime(i)) primes[cnt++]=i;
}
for(int i=0;i<cnt;i++){
i==0? printf("%d",primes[i]):printf(" %d",primes[i]);
}
printf("\n");
for(int i=2;i<=n;i++){
int x=i;
for(int j=0;j<cnt && primes[j]<=x;){
if(x%primes[j]==0){
++count[primes[j]];
x=x/primes[j];
}else{
++j;
}
}
}
printf("%d!=",n);
for(int i=0;i<cnt;i++){
i==0? printf("%d",count[primes[i]]):printf(" %d",count[primes[i]]);
}
printf("\n");
}
return 0;
}
5.4.3 三角形的有向面积:如图
注:三角形面积的其他计算方式,海伦公式:s=sqrt(p(p-a)(p-b)(p-c)),p=(a+b+c)/2