zoukankan      html  css  js  c++  java
  • 10.6 noip模拟试题

    更正:第三组:不存在相同的字符|str|=26,26<=n<=100

    60

    /*
    呵呵哒~这题
    正解还在研究....
    因为没有题解只有个std还在看
    不过乱搞一下可以70(数据好像有问题只有60)
    首先一个字母的不说了
    n<=5的暴力 不过吧 卡纯暴力
    +个小小的剪枝就是只找危险串的前len-1位
    最后一位枚举的时候判一下 这样能快一点
    另外%30没有重复的串的话dp一下
    f[i]表示前i位的方案数 先不考虑不合法的
    那就是26^i 再减去f[i-len]就是说除了那len位危险的
    剩下的有几种
    正解好像巧妙用fail数组+位数dp 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define mod 1000000007
    #define ll long long
    using namespace std;
    ll n,len,f[100010];
    char s[100010],D[100010];
    bool vis[100010];
    long long ans;
    void Dfs(int step)
    {
        if(step==n+1){
            ans++;
            if(ans>=mod) ans%=mod;
        }
        else{
            bool flag=(step<len-1)||(!equal(s+step-len+1,s+step,D));
            for(char x='a'; x<='z'; x++){
                if(!flag&&x==D[len-1]) continue;
                s[step]=x;Dfs(step+1);
            }
        }
    }
    void Solve(){
        if(n==0)ans=0;
        else Dfs(1);
        cout<<ans<<endl;
    }
    void DP(){
        memset(f,0,sizeof(f));
        f[0]=1;
        for(int i=1;i<=n;i++){
            f[i]=f[i-1]*26%mod;
            if(i>=len)f[i]=((f[i]-f[i-len])%mod+mod)%mod;
        }
        cout<<f[n]<<endl;
    }
    int main()
    {
        freopen("helloworld.in","r",stdin);
        freopen("helloworld.out","w",stdout);
        while(cin>>n){
            scanf("%s",D);len=strlen(D);
            ans=0;memset(vis,0,sizeof(vis));
            int sum=0;
            if(n<=5){
                Solve();continue;
            }
            for(int i=0;i<len;i++){
                if(vis[D[i]-'a']==0)sum++;
                vis[D[i]-'a']=1;
            }
            if(sum==len){
                DP();continue;
            }
            if(len==1){
                ans++;
                for(int i=1;i<=n;i++)ans=ans*25%mod;
                cout<<ans<<endl;continue;
            }
        }
        return 0;
    }
    View Code

    更正:输出的顺序保证a<b

    更正:输出样例:0 1000000006

    /*读错题目 把a+b的min输出来了QAQ*/
    #include<iostream>
    #include<cstdio>
    #define mod 1000000007
    #define ll long long
    using namespace std;
    ll k,a[2][2],f[2][2];
    void mul(ll a[2][2],ll b[2][2]){
        ll c[2][2];c[0][0]=c[0][1]=c[1][0]=c[1][1]=0;
        for(ll i=0;i<2;i++)
            for(ll j=0;j<2;j++)
                for(ll k=0;k<2;k++)
                    c[i][j]=(c[i][j]+a[i][k]*b[k][j]%mod)%mod;
        for(ll i=0;i<2;i++)
            for(ll j=0;j<2;j++)
                a[i][j]=c[i][j];
    }
    int main()
    {
        freopen("gcd.in","r",stdin);
        freopen("gcd.out","w",stdout);
        cin>>k;
        if(k==1){
            cout<<"1 1"<<endl;
            return 0;
        }
        a[0][0]=a[0][1]=a[1][0]=1;
        f[0][0]=3;f[0][1]=2;
        k-=2;
        while(k){
            if(k&1)mul(f,a);
            k>>=1;mul(a,a);
        }
        cout<<f[0][1]<<" "<<f[0][0]<<endl;
        return 0;
    }
    View Code

    更正:模数1000000007

    50

    /*
    乱搞...
    不会统计方案数 0...0
    用匈牙利搞一下P==1的情况
    还有几个点是暴力的 这样可以50分 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 100010
    #define mod 1000000007
    using namespace std;
    int T,P,n,head[maxn],num,f[maxn],match[maxn],ans,sum,C[maxn];
    struct node{
        int v,pre;
    }e[maxn*2];
    struct edge{
        int u,v;
    }c[maxn];
    void Add(int from,int to){
        num++;e[num].v=to;
        e[num].pre=head[from];
        head[from]=num;
    }
    int Dfs(int u){
        for(int i=head[u];i;i=e[i].pre){
            int v=e[i].v;
            if(f[v])continue;f[v]=1;
            if(match[v]==0||Dfs(match[v])){
                match[v]=u;return 1;
            }
        }
        return 0;
    }
    void Mx(){
        for(int i=1;i<=n;i++)if(C[i]){
            memset(f,0,sizeof(f));
            ans+=Dfs(i);
        }
        if(P==1)printf("%d
    ",ans);
        if(P==2)printf("%d 1
    ",ans);
    }
    void dfs(int now,int s){
        if(now==n){
            if(s>ans){
                ans=s;sum=1;
            }
            else if(s==ans)sum++,sum%=mod;
            return;
        }
        if(f[c[now].u]==0&&f[c[now].v]==0){
            f[c[now].u]=1;f[c[now].v]=1;
            dfs(now+1,s+1);
            f[c[now].u]=0;f[c[now].v]=0;
        }
        dfs(now+1,s);
    }
    void Mxx(){
        dfs(1,0);
        printf("%d %d
    ",ans,sum);
    }
    void Go(int now,int from){
        C[now]=!C[from];
        for(int i=head[now];i;i=e[i].pre){
            int v=e[i].v;
            if(v!=from)Go(v,now);
        }
    }
    int main()
    {
        freopen("hungary.in","r",stdin);
        freopen("hungary.out","w",stdout);
        scanf("%d%d",&T,&P);
        while(T--){
            num=0;ans=0;sum=0;
            memset(f,0,sizeof(f));
            memset(head,0,sizeof(head));
            memset(match,0,sizeof(match));
            scanf("%d",&n);
            int u,v;
            for(int i=1;i<n;i++){
                scanf("%d%d",&u,&v);
                Add(u,v);Add(v,u);
                c[i].u=u;c[i].v=v;
            }
            Go(1,0);
            if(P==1||n>=1000){Mx();continue;}
            if(P==2){Mxx();continue;}
        }
        return 0;
    }
    View Code

    100

    /*
    正解树形dp
    忽略的他是棵 树 树 树.....
    f[i][0 1]表示有没有连i的儿子
    然后顺便统计方案数.... 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #define maxn 100010
    #define mod 1000000007
    #define ll long long
    using namespace std;
    ll T,P,n,head[maxn],num,f[maxn][2],g[maxn][2],L,R[maxn],l,r[maxn],son[maxn];
    struct node{
        ll v,pre;
    }e[maxn*2];
    ll init(){
        ll x=0,f=1;char s=getchar();
        while(s<'0'||s>'9'){if(s=='0')f=-1;s=getchar();}
        while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
        return x*f;
    }
    void Add(ll from,ll to){
        num++;e[num].v=to;
        e[num].pre=head[from];
        head[from]=num;
    }
    void Clear(){
        num=0;
        memset(f,0,sizeof(f));
        memset(g,0,sizeof(g));
        memset(head,0,sizeof(head));
    }
    void DP(ll now,ll from){
        g[now][0]=1;
        ll mx,sum;
        for(int i=head[now];i;i=e[i].pre){
            ll v=e[i].v;
            if(v==from)continue;
            DP(v,now);//x不连儿子 儿子们可连可不连 
            mx=max(f[v][1],f[v][0]);sum=0;
            if(mx==f[v][1])sum+=g[v][1];
            if(mx==f[v][0])sum+=g[v][0];
            g[now][0]=g[now][0]*sum%mod;
            f[now][0]+=mx;
        }
        //x连某个儿子 这个不选 其他的连或者不连 
        L=0;l=1;ll S=0;
        for(int i=head[now];i;i=e[i].pre) 
            if(e[i].v!=from)son[++S]=e[i].v;
        R[S+1]=0;r[S+1]=1;
        for(int i=S;i>=1;i--){
            ll v=son[i];sum=0;
            mx=max(f[v][1],f[v][0]);
            if(mx==f[v][1])sum+=g[v][1];
            if(mx==f[v][0])sum+=g[v][0];
            R[i]=R[i+1]+mx;
            r[i]=r[i+1]*sum%mod;
        }
        for(int i=1;i<=S;i++){
            ll v=son[i];
            mx=L+f[v][0]+R[i+1]+1;
            if(mx>f[now][1]){
                f[now][1]=mx;
                g[now][1]=l*g[v][0]%mod*r[i+1]%mod;
            }
            else if(mx==f[now][1])
                g[now][1]=(g[now][1]+l*g[v][0]%mod*r[i+1]%mod)%mod;
            sum=0;
            mx=max(f[v][1],f[v][0]);
            if(mx==f[v][1])sum+=g[v][1];
            if(mx==f[v][0])sum+=g[v][0];
            l=l*sum%mod;L+=mx;
        }
    }
    int main()
    {
        freopen("hungary.in","r",stdin);
        freopen("hungary.out","w",stdout);
        T=init();P=init();
        while(T--){
            n=init();
            ll u,v;Clear();
            for(int i=1;i<n;i++){
                u=init();v=init();
                Add(u,v);Add(v,u);
            }
            DP(1,0);ll sum,mx;
            mx=max(f[1][0],f[1][1]);sum=0;
            if(mx==f[1][0])sum+=g[1][0],sum%=mod;
            if(mx==f[1][1])sum+=g[1][1],sum%=mod;
            if(P==1)cout<<mx<<endl;
            if(P==2)cout<<mx<<" "<<sum<<endl;
        }
        return 0;
    }
    View Code

     

     60

    /*
    正解还在看....这尼玛考试不发题解不讲解
    就给个std看啊看看啊看 蒟蒻表示压力很大啊
    这题乱搞的 有bug 似乎改不了了....
    60 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 210
    #define inf 1000000000
    using namespace std;
    int n,m;
    double g[maxn][maxn],ans=inf;
    struct node{
        int u,v;
        double t;
    }e[maxn*100];
    void Floyed(){
        for(int k=1;k<=n;k++)
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    if(g[i][k]+g[k][j]<g[i][j])
                        g[i][j]=g[i][k]+g[k][j];
    }
    void Solve(){
        for(int k=1;k<=m;k++){
            int u=e[k].u,v=e[k].v;
            double t=e[k].t;
            double r1=0,r2=0;
            for(int i=1;i<=n;i++){
                if(g[i][u]>g[i][v]){
                    if(r1<g[i][v])r1=g[i][v];
                }
                if(g[i][u]<g[i][v]){
                    if(r2<g[i][u])r2=g[i][u];
                }
                if(g[i][u]==g[i][v]){
                    double tmp=g[i][u];
                    if(r1<r2&&r2<tmp)r2=tmp;
                    if(r1>r2&&r1<tmp)r1=tmp;
                }
            }
            double r=r1+r2+t;r=r/2.0;
            double R;
            if(r>=r1&&r<=r1+t)R=r;
            else if(r<r1)R=r1;
            else R=r2;
            if(R<ans)ans=R;
        }
    }
    int main()
    {
        freopen("radius.in","r",stdin);
        freopen("radius.out","w",stdout);
        scanf("%d%d",&n,&m);
        int u,v;double t;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                g[i][j]=inf;
        for(int i=1;i<=m;i++){
            scanf("%d%d%lf",&u,&v,&t);
            if(t<g[u][v])g[u][v]=t;
            if(t<g[v][u])g[v][u]=t;
            e[i].u=u;e[i].v=v;e[i].t=t;
        }
        for(int i=1;i<=n;i++)g[i][i]=0;
        Floyed();Solve();
        printf("%.2f
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    Linux 笔记
    查看 Linux 系统版本信息
    在网站中添加 https 百度分享
    Linux 中 Xampp 的 https 安全证书配置
    Windows 笔记
    Linux 笔记
    CentOS7 自定义登录前后欢迎信息
    构建器内部的多形性方法的行为
    编译dubbo项目方法
    《Thing in java》多态
  • 原文地址:https://www.cnblogs.com/yanlifneg/p/5935032.html
Copyright © 2011-2022 走看看