原题链接:K-进制数
解题思路:
这是第一次解法,然而当K值很大时(k>2),数的基数将会非常大,会报超时,所有效率将非常低,故做了优化,
改成对二进制数的遍历,问题解决
#include<stdio.h>
int main(){
int i,j,d;
int n,k;
long num=0,num1=0;
int s[20]={1};
scanf("%d%d",&n,&k);
while(s[0]!=0){
int flag1=0;
for(i=0;i<n-1;i++)
if(s[i]==0&&s[i+1]==0){
flag1++;
}
if(flag1==0) num++;
else if(flag1!=0) num1++;
int flag=1; d=n-1;
while(flag==1){ //如果d位上变成0,则进位加1
flag=0;
s[d]=(s[d]+1)%k; //对K进制进行遍历
if(s[d]==0){
d--;flag=1;
}
}
}
printf("%d",num);
return 0;
}在一个N位K进制数中,每一位数无非两种情况:
1.为0;
2.不为0
故在第二次代码中,先遍历一次n位的二进制数,表示出数字0的分布情况,统计出非0的个数i,然后每种分
布情况的无效数的个数即为 knum=(k-1)^i; 统计完所有的knum,即为所有无效数字的个数
最后:
所有有效数的个数 = 所有不同的N位K进制数的个数 - 无效数字的个数
参考代码:
#include<stdio.h>
int main(){
int i,j,d;
int n,k,sum=0;
long num,num1=0,num2=1;
int s[20]={1};
scanf("%d%d",&n,&k);
while(s[0]!=0){
int flag1=0;
for(i=0;i<n-1;i++)
if(s[i]==0&&s[i+1]==0){
flag1++;
}
long knum=1;
if(flag1!=0) //统计二进制数无效的个数
for(i=0;i<n;i++)
if(s[i]!=0) knum*=k-1;
if(flag1!=0) num1+=knum; //当无效时才加上无效个数
int flag=1; d=n-1;
while(flag==1){ //如果d位上变成0,则进位加1
flag=0;
s[d]=(s[d]+1)%2; //改成对2进制进行遍历
if(s[d]==0){
d--;flag=1;
}
}
}
for(i=1;i<=n;i++){ //统计出有多少个不同的数
num=k-1;
for(j=1;j<i;j++){
num*=k;
}
sum+=num;
}
for(i=1;i<n;i++) //统计1~1000...0(n位)有多少不同的数
num2*=k;
printf("%d",sum-num2-num1+1);
return 0;
}0.0分
0 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复