第五章基础题目选解



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 三角形的有向面积:如图

第五章基础题目选解_第1张图片

注:三角形面积的其他计算方式,海伦公式:s=sqrt(p(p-a)(p-b)(p-c)),p=(a+b+c)/2





你可能感兴趣的:(c,算法,字符串,数组,字符串比较)