c++编程题目,求1到N之间数字1出现的个数。程序不用写,告诉我规律就好,自己写的老是超时

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++编程题目,求1到N之间数字1出现的个数。程序不用写,告诉我规律就好,自己写的老是超时相关的知识,希望对你有一定的参考价值。

#include #define MAX 1001 //1001表示这个大数N的阶层结果最多只能是1000位,注意 下面的程序是从a[1]开始存数 using namespace std; /************** *计算N的阶乘 ************** */ int jisuan(int n,int a[]) int i,j; //flag 用来存储计... 参考技术A #include #include using namespace std; #define MAX_DIGITAL 10000 void PrintFactorial(unsigned int n) vector r(1, 1); size_t j = 0; for (unsigned int i = 1; i 0) r.push_back(carry); cout

hdu6602---线段树

Longest Subarray

题意:一个数列,每个元素大小都在1到C之间,求一个最长的子串,满足在这个子串中1到C之间的每个数字要么出现0次,要么出现至少K次。

题解:(i)从1到n枚举右端点,维护一个(tree[j])表示在(i)为右端点时以(j)为左端点可行的个数(这里的可行是指对于1到C之间的某一个数是否可行,即(j)(i)之间(X)的个数是否满足题意,(Xepsilon(1,C)))。那么对于固定的(i)显然当(tree[j]==C)([j,i])是一个可行区间,找出最小的(j)即可. 上述操作在线段树上维护.

#include<bits/stdc++.h>
using namespace std;
const int maxn=100005;
int n,c,k,a[100005];
int tree[maxn*4],tag[maxn*4];
inline int ls(int x){
    return x<<1;
}
inline int rs(int x){
    return x<<1|1;
}
void change(int root,int del){
    tree[root]+=del;
    tag[root]+=del;
}
void pushdown(int root,int l,int r){
    if(!tag[root]) return;
    int mid=(l+r)>>1;
    change(ls(root),tag[root]);
    change(rs(root),tag[root]);
    tag[root]=0;
}
void update(int root,int l,int r,int il,int ir,int del){
    if(r<il||l>ir) return;
    if(l>=il&&r<=ir) {
        tree[root] += del;
        tag[root] += del;
        return;
    }
    pushdown(root,l,r);
    int mid=(l+r)>>1;
    update(ls(root),l,mid,il,ir,del);
    update(rs(root),mid+1,r,il,ir,del);
    tree[root]=max(tree[ls(root)],tree[rs(root)]);
}
int ask(int root,int l,int r,int il,int ir){
    if(r<il||l>ir) return -1;
    if(tree[root]<c) return -1;
    if(l==r) return l;
    pushdown(root,l,r);
    int mid=(l+r)>>1;
    int tmp=ask(ls(root),l,mid,il,ir);
    if(tmp>0) return tmp;
    return ask(rs(root),mid+1,r,il,ir);
}
vector<int> pos[maxn];
int main(){
    while(~scanf("%d%d%d",&n,&c,&k)) {
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=1;i<=c;i++) {
            pos[i].clear();
        }
        if(k==1){
            printf("%d
",n); continue;
        }
        int nn=n*4;
        for(int i=1;i<=nn;i++) tree[i]=0,tag[i]=0;
        int ans=0;
        for(int i=1;i<=n;i++){
            pos[a[i]].push_back(i);
            update(1,1,n,i,i,c-1);
            int siz=pos[a[i]].size();
            if(siz>=1){
                int l=siz-2,r=siz-1;
                if(l<0) l=1;
                else l=pos[a[i]][l]+1;
                r=pos[a[i]][r]-1;
                if(l<=r) update(1,1,n,l,r,-1);
            }
            if(siz>=k){
                int l=siz-k-1,r=siz-k;
                if(l<0) l=1;
                else l=pos[a[i]][l]+1;
                r=pos[a[i]][r];
                update(1,1,n,l,r,1);
            }
            int tmp=ask(1,1,n,1,i);
            if(tmp>0) ans=max(ans,i-tmp+1);
        }
        printf("%d
",ans);
    }
    return 0;
}

以上是关于c++编程题目,求1到N之间数字1出现的个数。程序不用写,告诉我规律就好,自己写的老是超时的主要内容,如果未能解决你的问题,请参考以下文章

C语言 N为正整数,计算从1到N的所有整数中包含数字1的个数

编程之美-1的个数

求一个区间[a,b]中数字1出现的次数

输出[m,n]之间的素数,用c语言编程怎么写。谢谢,

C++编程基础题解:插入排序

求一个整数区间(从1到n)内1出现的次数