zoukankan      html  css  js  c++  java
  • 第4题:质数

    先讲一下80分的作法,尺取

    #include <bits/stdc++.h>
    using namespace std;
    bool a[1000010];
    int x[1000100];
    int main(){
        int T;
        cin>>T;
        while(T--){
            int n;
            cin>>n;
            memset(a,1,sizeof(a));
            for(int i=2;i*i<=n;i++)
            	if(a[i])
            		for(int j=i*i;j<=n;j+=i)a[j]=0;
            int s=0;
            for(int i=2;i<=n;i++)
            	if(a[i])x[++s]=i;
            int sum=0,ans=0,ai=0;
            for(int i=1;i<=s;i++){
            	sum+=x[i];
            	while(sum>n)sum-=x[ai],ai++;
            	if(sum==n)ans++;
            }cout<<ans<<endl;
        }
        return 0;
    }
    
    

    这种作法时间复制度是很高的,80分,其实重要的不是ai,而是数据组数n,n<=10^6

    于是我开始了打表

    10^5 打了几分钟,可是

    好尴尬呀!

    显然是RP不行,估计省赛都用光了。

    更好的做法106比105大了好多,所以可以用类似于记忆化的东西来优化,再加上快读,快出

    #include <bits/stdc++.h>
    using namespace std;
    bool a[1000010];
    int x[1000100],b[1000010];
    inline void write(int x){
        if(x>9)write(x/10);
        putchar(x%10+'0');
    }
    inline int read(){
        register int x=0,f=1; register char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f*=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        return x*f;
    }
    int main(){
        memset(b,-1,sizeof(b));
        int T;
        T=read();
        while(T--){
            int n=read();
            if(b[n]!=-1){
            	write(b[n]);
            	putchar('
    ');
            }else{
                memset(a,1,sizeof(a));
                for(int i=2;i*i<=n;i++)
                	if(a[i])
                		for(int j=i*i;j<=n;j+=i)a[j]=0;
                int s=0;
                for(int i=2;i<=n;i++)
                	if(a[i])x[++s]=i;
                int sum=0,ans=0,ai=0;
                for(int i=1;i<=s;i++){
                	sum+=x[i];
                	while(sum>n)sum-=x[ai],ai++;
                	if(sum==n)ans++;
                }b[n]=ans;
                write(b[n]);
            	putchar('
    ');
            }
        }
        return 0;
    }
    
    

    哇,速度真是快了不是,不过还是80分。

    我们还可以将素数表和装素数的数组,放在外面完成,避免重复,浪费时间。

    #include <bits/stdc++.h>
    using namespace std;
    bool a[1000010];
    int x[1000100],b[1000010];
    inline void write(int x){
        if(x>9)write(x/10);
        putchar(x%10+'0');
    }
    inline int read(){
        register int x=0,f=1; register char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f*=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        return x*f;
    }
    int main(){
    	int s=0;
    	memset(b,-1,sizeof(b));
        int T;
        T=read();
        for(int i=2;i*i<=100000;i++)
    	    if(!a[i])
    	    	for(int j=i*i;j<=100000;j+=i)a[j]=1;
    	for(int i=2;i<=100000;i++)
    	    if(!a[i])x[++s]=i;
        while(T--){
            int n=read();
            if(b[n]!=-1){
            	write(b[n]);
            	putchar('
    ');
    		}else{
    	        int sum=0,ans=0,ai=0;
    	        for(int i=1;i<=s;i++){
    	        	sum+=x[i];
    	        	while(sum>n)sum-=x[ai],ai++;
    	        	if(sum==n)ans++;
    	        }b[n]=ans;
    			write(b[n]);
            	putchar('
    ');
    		}
        }
        return 0;
    }
    
    

    但是还是TLE

    于是我们干脆把仅剩的一个循环在搞到循环外

    #include <bits/stdc++.h>
    using namespace std;
    bool a[100010];
    int x[100100],b[100010];
    inline void write(int x){
        if(x>9)write(x/10);
        putchar(x%10+'0');
    }
    inline int read(){
        register int x=0,f=1; register char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f*=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        return x*f;
    }
    int main(){
    	int s=0;
        int T;
        T=read();
        for(int i=2;i*i<=100000;i++)
    	    if(!a[i])
    	    	for(int j=i*i;j<=100000;j+=i)a[j]=1;
    	for(int i=2;i<=100000;i++)
    	    if(!a[i]){
    	    	s++;
    	    	x[s]=x[s-1]+i;
    		}
    	for(int i=0;i<s;i++)
    		for(int j=i+1;j<=s;j++){
    			if(x[j]-x[i]>100000)break;
    			b[x[j]-x[i]]++;
    		}
        while(T--){
            int n=read();
            write(b[n]);
            putchar('
    ');
        }
        return 0;
    }
    
    

    基本很龚胤翔一至

  • 相关阅读:
    js字符串String常用方法
    flexible.js结合rem实现移动端自适应布局
    Django API验证(令牌)
    错误堆栈信息
    JS Ajax异步请求发送列表数据后面多了[]
    根据后端传的时间前端js进行倒计时
    Vue select 下拉菜单
    centos 6.x 部署uwsgi+flask项目
    css 让背景图片不停旋转
    supervisor管理uwsgi
  • 原文地址:https://www.cnblogs.com/zhaohaikun/p/12816994.html
Copyright © 2011-2022 走看看