第五章基础题目选解

时间:2021-06-01 07:17:36


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