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