zoukankan      html  css  js  c++  java
  • Qbxt 模拟赛&&day-8

    /*
    今天的题目还是比较不错的.
    今天考的很烂还是依旧的弱.
    快考试了加油吧.
    Bless all.
    */
    注:所有题目的时间限制均为 1s,内存限制均为 256MB。
    1.第K小数 (number.cpp/c/pas)
    【问题描述】
    有两个正整数数列,元素个数分别为N和M。从两个数列中分别任取一个数 相乘,这样一共可以得到N*M个数,询问这N*M个数中第K小数是多少。
    【输入格式】
    输入文件名为number.in。
    输入文件包含三行。
    第一行为三个正整数N,M和K。
    第二行为N个正整数,表示第一个数列。
    第三行为M个正整数,表述第二个数列。
    【输出格式】
    输出文件名为number.out。
    输出文件包含一行,一个正整数表示第K小数。
    【输入输出样例1】
    number.in
    2 3 4
    1 2
    2 1 3
    number.out  
    3
    【输入输出样例2】
    number.in
    5 5 18
    7 2 3 5 8
    3 1 3 2 5
    number.out  
    16
    【数据规模与约定】
    ![这里写图片描述](https://img-blog.csdn.net/20161110205658499)
    ![这里写图片描述](https://img-blog.csdn.net/20161110205712476)
    
    /*
    二分答案.
    O((n+m)logk). 
    然而本蒟蒻一开始只能暴力.
    其实一开始也想到这个单调性了.
    但想了想ans并不单调啊.
    然后就跪了orz.
    二分找下界.
    检验的时候因为确定了一个序列之后
    另一个序列的元素就单调了.
    so 我们二分一个答案
    就可以计算出比它小的数的个数.
    这个显然是单调的.
    */
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define MAXM 25000001
    #define MAXN 200001
    #define LL long long
    using namespace std;
    LL n,m,k;
    LL a[MAXN],b[MAXN],tot,ans;
    LL read()
    {
        LL x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    bool check(LL x)
    {
        int p=m;tot=0;
        for(int i=1;i<=n;i++)
        {
            while(p&&a[i]*b[p]>=x) p--;
            tot+=p;
        }
        if(tot>=k) return true;
        return false;
    }
    inline void erfen(LL l,LL r)
    {
        LL mid;
        while(l+1<r)
        {
            mid=(l+r)>>1;
            if(check(mid)) ans=mid,r=mid;
            else l=mid;
        }
        cout<<l;
    }
    int main()
    {
        freopen("number.in","r",stdin);
        freopen("number.out","w",stdout);
        n=read(),m=read(),k=read();
        for(int i=1;i<=n;i++) a[i]=read();
        for(int i=1;i<=m;i++) b[i]=read();
        sort(a+1,a+n+1),sort(b+1,b+m+1);
        erfen(0,a[n]*b[m]);
        return 0;
    }

    2. dwarf tower (dwarf.cpp/c/pas)
    【问题描述】
    Vasya在玩一个叫做”Dwarf Tower”的游戏,这个游戏中有n个不同的物品, 它们的编号为1到n。现在Vasya想得到编号为1的物品。 获得一个物品有两种方式:
    1. 直接购买该物品,第i件物品花费的钱为ci
    2. 用两件其他物品合成所需的物品,一共有m种合成方式。
    请帮助Vasya用最少的钱获得编号为1的物品。
    【输入格式】
    第一行有两个整数n,m(1<=n<=10000,0<=m<=100000),分别表示有n种物品以 及m种合成方式。
    接下来一行有n个整数,第i个整数ci表示第i个物品的购买价格,其中 0<=ci<=10^9。
    接下来m行,每行3个整数ai,xi,yi,表示用物品xi和yi可以合成物品ai,其 中(1<=ai,xi,yi<=n; ai<>xi, xi<>yi, yi<>ai)
    【输出格式】
    一行,一个整数表示获取物品 1 的最少花费。
    输入样例:
    5 3
    5 0 1 2 5
    5 2 3
    4 2 3
    1 4 5
    输出样例:
    2
    【数据规模与约定】
    60%的数据, n<=100
    100%的数据, n<=10000, m<=100000

    /*
    75.
    愚蠢的我建了一棵树.
    还能自动判环2333.
    但不知道为什么会W.
    望路过大神指教. 
    */
    #include<iostream>
    #include<cstdio>
    #include<vector>
    #define MAXN 10001
    using namespace std;
    int w[MAXN],n,m,f[MAXN];
    vector<int>son[MAXN];
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    inline int slove(int u)
    {
        if(f[u]) return f[u];
        f[u]=w[u];
        for(int i=0;i<son[u].size();i+=2)
          f[u]=min(w[u],slove(son[u][i])+slove(son[u][i+1]));
        return f[u];
    }
    int main()
    {
        freopen("dwarf.in","r",stdin);
        freopen("dwarf.out","w",stdout);
        int x,y,z;
        n=read(),m=read();
        for(int i=1;i<=n;i++) w[i]=read();
        if(!m)
        {
            printf("%d",w[1]);
            return 0;
        }
        for(int i=1;i<=m;i++)
        {
            x=read(),y=read(),z=read();
            son[x].push_back(y),son[x].push_back(z);
        }
        cout<<slove(1);
        return 0;
    }
    /*
    spfa松弛.
    一开始也想这样做来着.
    但是建图的时候傻眼了.
    其实三个点的话就那两个点作为(u,v).
    另一个点辅助更新就好了.
    一开始让所有点都入队
    是为了保证能够正确松弛.
    */
    #include<iostream>
    #include<cstdio>
    #include<queue>
    #define MAXN 10001
    using namespace std;
    int n,m,dis[MAXN],head[MAXN],cut;
    bool b[MAXN];
    queue<int>q;
    struct data{int v,next,x;}e[MAXN*20];
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    inline void add(int v,int u,int x)
    {
        e[++cut].v=v;
        e[cut].next=head[u];
        e[cut].x=x;
        head[u]=cut;
    }
    inline void bfs()
    {
        int u;
        for(int i=1;i<=n;i++) b[i]=true;
        while(!q.empty())
        {
            u=q.front();q.pop();b[u]=false;
            for(int i=head[u];i;i=e[i].next)
            {
                int v=e[i].v,x=e[i].x;
                if(dis[v]>dis[x]+dis[u])
                {
                    dis[v]=dis[x]+dis[u];
                    if(!b[v]) b[v]=true,q.push(v);
                }
            }
        }
    }
    int main()
    {
        freopen("dwarf.in","r",stdin);
        freopen("dwarf.out","w",stdout);
        int x,y,z;
        n=read(),m=read();
        for(int i=1;i<=n;i++) dis[i]=read(),q.push(i);
        if(!m)
        {
            printf("%d",dis[1]);
            return 0;
        }
        for(int i=1;i<=m;i++)
        {
            x=read(),y=read(),z=read();
            add(x,y,z),add(x,z,y);
        }
        bfs();
        printf("%d",dis[1]);
        return 0;
    }

    3. abcd (abcd.cpp/c/pas)
    【问题描述】
    有4个长度为N的数组a,b,c,d。现在需要你选择N个数构成数组e,数组e满足 a[i]≤e[i]≤b[i]以及这里写图片描述
    并且使得这里写图片描述最大。
    【输入格式】
    输入文件名为abcd.in。
    输入文件共 N+1 行。
    第 1 行包含1个正整数N。
    第 i+1 行包含4个整数a[i],b[i],c[i],d[i]。
    【输出格式】
    输出文件名为abcd.out。
    输出共1行,包含1个整数,表示所给出公式的最大值。
    输入数据保证一定有 解。
    【输入输出样例1】
    abcd.in
    5
    - 1 1 2 5
    -2 2 1 2
    0 1 1 3
    -2 -1 3 10
    -2 2 3 9
    abcd.out
    2
    【输入输出样例2】
    abcd.in
    10
    1 10 1 7
    -10 10 2 0
    -10 10 2 2
    -10 10 2 0
    1 10 1 0
    -10 10 2 0
    10 10 2 0
    1 10 1 0
    -10 10 2 0
    1 10 1 0
    abcd.out
    90
    【输入输出样例3】
    abcd.in
    10
    1 10 1 0
    -10 10 2 2
    -10 10 2 2
    -10 10 2 2
    1 10 1 0
    -10 10 2 2
    -10 10 2 2
    1 10 1 0
    -10 10 2 2
    1 10 1 0
    abcd.out
    -4
    【数据规模与约定】
    对于 20%的数据, N≤10, -2≤a[i]

    /*
    20.
    纯暴力(剪枝忽视掉). 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<ctime>
    #define MAXN 201
    using namespace std;
    int a[MAXN],b[MAXN],c[MAXN],d[MAXN],n,ans=-1e9,tot,s[MAXN];
    int sum1[MAXN],sum2[MAXN];
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    inline void dfs(int t,int tot,int sum)
    {
        if(t==n+1)
        {
            if(!tot) 
            ans=max(ans,sum);
            return ;
        }
        for(int i=b[t];i>=a[t];i--)
        {
            if(tot+i*c[t]+sum1[t+1]<0) continue;
            dfs(t+1,tot+i*c[t],sum+i*d[t]);
        }
        return ;
    }
    int main()
    {
        freopen("abcd.in","r",stdin);
        freopen("abcd.out","w",stdout);
        n=read();
        for(int i=1;i<=n;i++)
          a[i]=read(),b[i]=read(),c[i]=read(),d[i]=read();
        for(int i=n;i>=1;i--) sum1[i]=sum1[i+1]+b[i]*c[i];
        dfs(1,0,0);
        printf("%d",ans);
        return 0;
    }
    /*
    60.
    f[i][y]表示从n到i构成y的最大值.
    从1点跑固定终点的单源DAG.
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<ctime>
    #define MAXN 202
    #define MAXM 100001
    using namespace std;
    int a[MAXN],b[MAXN],c[MAXN],d[MAXN],n,tot;
    int sum1[MAXN],sum2[MAXN],f[MAXN][MAXM*2+100],INF;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    inline int dfs(int t,int tot)
    {
        if(f[t][tot]!=INF) return f[t][tot];
        if(t==n+1)
        {
            if(tot==MAXM-1) return 0;
            return INF;
        }
        for(int i=b[t];i>=a[t];i--)
        {
            //if(tot+i*c[t]+sum1[t+1]<0) continue;
            f[t][tot]=max(f[t][tot],dfs(t+1,tot+i*c[t])+i*d[t]);
        }
        return f[t][tot];
    }
    int main()
    {
        freopen("abcd.in","r",stdin);
        freopen("abcd.out","w",stdout);
        memset(f,-127/3,sizeof f);INF=f[0][0];
        n=read();
        for(int i=1;i<=n;i++)
          a[i]=read(),b[i]=read(),c[i]=read(),d[i]=read();
        //for(int i=n;i>=1;i--) sum1[i]=sum1[i+1]+b[i]*c[i];
        printf("%d",dfs(1,MAXM-1));
        return 0;
    }
    /*
    正解多重背包.
    想不到吖想不到.
    对于∑e[i]*c[i]=0 ①
    和ans=∑b[i]*e[i] ②
    因为e[i]=[a[i],b[i]]等价于[0,b[i]-a[i]]+a[i];
    so 问题转化为使得
    ∑(b[i]-a[i])*c[i]+∑a[i]*c[i]=0
    且∑(b[i]-a[i])*d[i]+∑a[i]*d[i]最大.
    然后∑a[i]*c[i]和∑a[i]*d[i]是可以计算的.
    令V=∑a[i]*c[i](V<0),s[i]=b[i]-a[i].
    so 问题转化为在体积为-V的背包中取物品s[i]求最大值.
    可以从1(or n)跑固定起点和终点的DAG
    or二进制拆01背包or四边形单调队列等等...
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define MAXN 201
    #define MAXM 100001
    using namespace std;
    int n,a[MAXN],b[MAXN],c[MAXN],d[MAXN];
    int V,ans1,tot,w[MAXM],v[MAXM],f[MAXM];
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    inline int slove()
    {
        V*=-1;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=b[i];j<<=1)
              b[i]-=j,w[++tot]=d[i]*j,v[tot]=c[i]*j;
            if(b[i]) w[++tot]=d[i]*b[i],v[tot]=c[i]*b[i];
        }
        f[0]=0;
        for(int i=1;i<=tot;i++)
          for(int j=V;j>=v[i];j--)
            f[j]=max(f[j],f[j-v[i]]+w[i]);
        return f[V];
    }
    int main()
    {
        freopen("abcd.in","r",stdin);
        freopen("abcd.out","w",stdout);
        n=read();memset(f,-127/3,sizeof f);
        for(int i=1;i<=n;i++)
          a[i]=read(),b[i]=read(),c[i]=read(),d[i]=read(),
        V+=a[i]*c[i],b[i]-=a[i],ans1+=a[i]*d[i];
        printf("%d",slove()+ans1);
        return 0;
    }
  • 相关阅读:
    python写入csv文件中文乱码解决方案
    高质量代码有三要素:可读性、可维护性、可变更性
    CFile
    BMP格式图像的显示
    SAP BW 学习笔记(一)
    SAP BW 学习笔记(五)
    SAP BW 学习笔记(二)
    SAP BW 学习笔记(三)
    SAP BW 学习笔记(四)
    CRM 5.0 Marketing – BW integrated topics summary
  • 原文地址:https://www.cnblogs.com/nancheng58/p/10068159.html
Copyright © 2011-2022 走看看