叮咚叮咚


私信TA

用户名:13060009323

访问量:8981

签 名:

敲代码是一种工科生的艺术

等  级
排  名 4165
经  验 1702
参赛次数 0
文章发表 16
年  龄 21
在职情况 学生
学  校 四川工商学院
专  业

  自我简介:

解题思路:

         1.思路很简单,就是开个一维数组,模拟手算,作递增1的初始化,形如[1,2,3..n],注意理解题,因为这里只算位于m 到 n之间的幸运数个数,那算遍历数组,算到n就可以结束了。   

          2.我的算法中没有将删掉的数用后面的数补空位,是因为那样每一轮删除数字,都要对整个数组移位,时间复杂度太高,为O(n*n),果断超时

          3.因为没有将删除的数用后位数补上,说白了就是没有更新数的的下标。解决办法很简单,就是跳过空位,用step表示数字的实际下标( 姑且叫逻辑下标比较好理解些! ),更新下标step,满足整除情况时,删掉该位置的数字,即置为0
注意事项:  

           这里代码看起来两重循环 ,好像时间复杂度达到了o(n^2),但稍微想想,时间复杂度实际上是小了很多,

O(n*e),由于计算中,删掉的数字的个数是都是不定的,但可以肯定e是远小于n的

参考代码:

#include<iostream>
#define maxBit 1000050
using namespace std;

int main(){
	int a[maxBit],m,n,count=0,i=2,t;
	cin>>m>>n;	//	m < n <1000000
	if(n-m<=1)
	{    cout<<count; return 0;}   //m n之间没有数时,count为0
	for(int j=1;j<=n;j++)
		a[j]=j;		//初始化数列
	while(i<=n){
		while(a[i]==0)i++;
		int step=0;
			t=a[i];  //a[i]有可能也会被置0,不作除数,用t保存值
		for(int d=1;d<=n;d++){	//相关序号的数 置为0 
			if(a[d]!=0)		step++; //记录逻辑下标
		if(step%t==0&&step!=0)	a[d]=0;   
		}
		if(a[i]!=0) i++;      //如果算完了一轮没有删除a[i],则保留,指针i后移
	}
	for(i=m+1;i<n;i++)
		if(a[i]!=0) count++;
	cout<<count;
		return 0;
}


 

0.0分

0 人评分

  评论区