zoukankan      html  css  js  c++  java
  • 记codevs第一次月赛

    第一次参加这种有奖励的比赛(没错,我就是为猴子而去的

    一年没怎么碰代码果然手生,还是用没写多久的C++,差点全跪了

    T1数学奇才琪露诺:

    首先定义一个函数F(x),F(x)=x的各个数位上的数字和

    然后在区间[l,r]求F(x)k*p+q=x的所有x,按升序输出

    T1题解:

    枚举x肯定是不行的,F(x)的值只有0到81,我们枚举F(x)的值,然后算出F(x)k*p+q,看数位和是不是符合

    可能会爆int,所以要开long long

    #include <cstdio>
    #include <algorithm>
    #include <vector>
    #include <set>
    using namespace std;
    
    long long k,p,q,l,r,a[10000],tot;
    
    long long s(long long x){
        long long ss=0;
        while(x>0){
            ss+=x%10;
            x=x/10;
        }
        return ss;
    }
    
    long long pow(long long x,long long y){
        long long ipow=1;
        long long i;
        for(i=1;i<=y;++i)ipow=ipow*x;
        return ipow;
    }
    
    int main(){
        scanf("%lld%lld%lld%lld%lld",&k,&p,&q,&l,&r);
        long long i;
        tot=0;
        for(i=0;i<=81;++i){
            long long tmp;
            tmp=pow(i,k)*p+q;
            if((tmp>=0)&&(s(tmp)==i)&&(tmp>=l)&&(tmp<=r))a[++tot]=tmp;
        }
        sort(a+1,a+1+tot);
        printf("%lld
    ",tot);
        for(i=1;i<=tot;++i)printf("%lld ",a[i]);
        return 0;
    }
    T1

    T2完美拓印:

    给你一条轮廓线和一个印章,问有多少种方法可以让印章的一条边缘(上下两边)与轮廓线重合,印章可以180°旋转

    T2题解:

    我们注意到只要相邻两格的高度差一样就行,所以我们把相邻两项的差拿出来做kmp就行了

    注意要做四次kmp,下面平的也要考虑,还有就是特判n=1的情况

    #include <cstdio>
    #include <algorithm>
    #include <vector>
    #include <set>
    using namespace std;
    
    int n,m,a[1000100],b[1000100],nex[1000100],ans;
    
    int work(){
        int i,j;
        for(i=n-1;i>0;--i)a[i]=a[i-1]-a[i];
        nex[1]=0;
        nex[0]=0;
        for(i=2;i<n;++i){
            j=nex[i-1];
            while((j>0)&&(a[i]!=a[j+1]))j=nex[j];
            if(a[i]==a[j+1])nex[i]=j+1;
            else nex[i]=0;
        }
        i=0;j=0;
        while(j<m-1){
            if(a[i+1]==b[j+1])++i,++j;
            else
            if(i==0)++j;
            else i=nex[i];
            if(i==n-1){
                ++ans;
                i=nex[i];
            }
        }
        for(i=1;i<n;++i)a[i]=a[i-1]-a[i];
        return 0;
    }
    
    int swap(int &a,int &b){
        int t;
        t=a;a=b;b=t;
        return 0;
    }
    
    int main(){
        int i;
        ans=0;
        scanf("%d%d",&n,&m);
        for(i=0;i<n;++i)scanf("%d",&a[i]);
        for(i=0;i<m;++i)scanf("%d",&b[i]);
        if(n==1){
            printf("%d
    ",4*m);
            return 0;
        }
        for(i=m-1;i>0;--i)b[i]=b[i-1]-b[i];
        work();
        for(i=0;i<n/2;++i)swap(a[i],a[n-i-1]);
        for(i=0;i<n;++i)a[i]=-a[i];
        work();
        for(i=0;i<n;++i)a[i]=0;
        work();
        work();
        printf("%d
    ",ans);
        return 0;
    }
    T2

    T3幻影阁的难题:

    给你两棵树,你可以分别在两棵树上找一个点,然后在这两个点之间连一条长度为t的边

    1.求连边之后最长路的最小值

    2.求最长路的期望长度

    T3题解:

    首先我们看第一问,我们只要树dp算出从某个点出发的最长链,然后取两棵树的最小值相加再加t,但是我们还要考虑不经过新边的情况,那么就是原来树上的最长链,从这两个中取最大值就行了

    第二问要求期望,所以我们要把所有的情况都算出来,然后总长除以n*m,我们先把两棵树计算好的最长链排好序

    然后我们要计算的就是∑max(最长链,a[i]+b[j]),因为我们排好了序,所以对于每一个i,取最长链的是一段连续的区间,我们只要记一下前缀和就可以快速计算了

    #include <cstdio>
    #include <algorithm>
    #include <vector>
    #include <set>
    using namespace std;
    
    long long n,m,t,tot;
    long long nex[400400],las[400400],l[400400],aa[200200];
    long long s1[200200],s2[200200],fa[200200],fir[200200],q[200200],len[200200];
    bool f[200200];
    long long ss2[200200],g[200200];
    long long ans,ans1,ans2;
    
    int insert(int x,int y,int z){
        ++tot;
        l[tot]=z;
        las[tot]=y;
        nex[tot]=fir[x];
        fir[x]=tot;
    }
    
    int work(){
        int i,x,y,z;
        tot=0;
        for(i=1;i<=n;++i)fir[i]=0,f[i]=false,s1[i]=0,s2[i]=0;
        for(i=1;i<n;++i){
            scanf("%d%d%d",&x,&y,&z);
            insert(x,y,z);
            insert(y,x,z);
        }
        f[1]=true;
        int ll,rr;
        ll=1;rr=1;
        q[1]=1;
        for(;ll<=rr;++ll){
            int j;
            for(j=fir[q[ll]];j!=0;j=nex[j])
            if(!f[las[j]]){
                f[las[j]]=true;
                q[++rr]=las[j];
                len[rr]=l[j];
                fa[rr]=ll;
            }
        }
        len[1]=0;g[0]=0;
        s1[0]=0;s2[0]=0;
        for(i=n;i>1;--i){
            if(s1[i]+len[i]>s1[fa[i]])s2[fa[i]]=s1[fa[i]],s1[fa[i]]=s1[i]+len[i];
            else
            if(s1[i]+len[i]>s2[fa[i]])s2[fa[i]]=s1[i]+len[i];
        }
        long long tmp=2000000000;
        for(i=1;i<=n;++i){
            if(s1[i]+len[i]!=s1[fa[i]])g[i]=s1[fa[i]]+len[i];
            else g[i]=s2[fa[i]]+len[i];
            g[i]=max(g[i],g[fa[i]]+len[i]);
            tmp=min(tmp,max(g[i],s1[i]));
            ans1=max(ans1,g[i]+s1[i]);
        }
        ans2+=tmp;
        return 0;
    }
    
    long long gcd(long long a,long long b){
        if(b==0)return a;
        return gcd(b,a%b);
    }
    
    int main(){
        scanf("%d%d%d",&n,&m,&t);
        ans=0;ans1=0;ans2=0;
        work();
        int i,j;
        for(i=1;i<=n;++i)aa[i]=max(g[i],s1[i]);
        swap(n,m);
        work();
        for(i=1;i<=n;++i)g[i]=max(g[i],s1[i]);
        sort(aa+1,aa+1+m);
        sort(g+1,g+1+n);
        ans1-=t;
        ss2[1]=aa[1];
        for(i=2;i<=m;++i)ss2[i]=ss2[i-1]+aa[i];
        j=m;
        for(i=1;i<=n;++i){
            while((j>0)&&(g[i]+aa[j]>ans1))--j;
            ans+=ans1*j+g[i]*(m-j)+ss2[m]-ss2[j];
        }
        ans+=t*n*m;
        ans2=max(ans2+t,ans1+t);
        printf("%lld
    ",ans2);
        long long tmp;
        tmp=gcd(ans,n*m);
        printf("%lld",ans/tmp);
        printf("/");
        printf("%lld",n*m/tmp);
        return 0;
    }
    T3
  • 相关阅读:
    jquery.tmpl.js 模板引擎用法
    var 的使用
    BUG集锦
    jquery Ajax异步请求之session
    找到多个与名为“Login”的控制器匹配的类型
    蒙板 模态对话框
    mvc通过ActionFilterAttribute做登录检查
    MVC 分页
    MVC 创建线程内的db单例
    Servlet生命周期中的service方法分析
  • 原文地址:https://www.cnblogs.com/Randolph87/p/4678058.html
Copyright © 2011-2022 走看看