解题思路:

这是第一次解法,然而当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;
}




点赞(4)
 

0.0分

0 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论