• 集训队日常训练20180518-DIV2


    A.3232

    n个物品,换取要花积分,问刚好花完积分能换最大多少价值的物品。

    多重背包。

    #include <bits/stdc++.h>
    using namespace std;
    int t[1005];
    int main()
    {
        int m,n,i,a,b,c,T,j,k;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&m,&n);
            memset(t,0,sizeof(t));
            for(k=0;k<n;k++)
            {
                scanf("%d%d%d",&a,&b,&c);
                if(t[c]<a)
                    t[c]=a;
                for(i=0;i<=b;i++)
                {
                    for(j=m;j>=c;j--)
                    {
                        if(j-c*i>=0&&t[j-c*i]&&t[j-c*i]+a*i>t[j])
                            t[j]=t[j-c*i]+a*i;
                    }
                }
    
            }
            if(t[m]) printf("The maximum value is %d.
    ",t[m]);
            else printf("This is impossible.
    ");
        }
        return 0;
    }
    A.cpp

    B.3196

    医生优先处理级别最高的病人,给n件发生的事,对于每个OUT输出。

    优先队列。

    #include <bits/stdc++.h>
    using namespace std;
    #define inf 0x3f3f3f3f
    struct node
    {
        int a, b;
        friend bool operator<(node a, node b)
        {
            if(a.a != b.a) return a.a < b.a;
            return a.b > b.b;
        }
    };
    int main()
    {
        int n;
        while(cin >> n)
        {
            priority_queue<node> qu[4];
            string str;
            int cnt = 0;
            for(int i = 1; i<= n; i++)
            {
                cin >>str;
                if(str == "IN")
                {
                    int a,b; cin >> a >> b;
                    qu[a].push({b,++cnt});
                }
                else if(str == "OUT")
                {
                    int a; cin >> a;
                    if(!qu[a].empty()) cout <<qu[a].top().b << endl, qu[a].pop();
                    else cout << "EMPTY
    ";
                }
            }
        }
        return 0;
    }
    B.cpp

    C.4705

    给一个数字串问取出一个连续的若干位能组成的最大素数。

    暴力。

    #include <bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        string str;
        while(cin >>str)
        {
            int maxx = -1;
            for(int i = 0; i < str.size(); i++)
            {
                int temp = 0;
                for(int j = i; j < str.size(); j++)
                {
                    temp = temp*10 + str[j]-'0';
                    int f = 0;
                    for(int k = 2; k <= sqrt(temp); k++)
                    {
                        if(temp % k == 0) {f = 1; break;}
                    }
                    if(temp != 1 && !f) maxx = max(maxx,temp);
                }
            }
            if(maxx == -1) cout << "None
    ";
            else cout << maxx <<endl;
        }
        return 0;
    }
    C.cpp

    D.3293

    给一个数A,一个数B,问AB的二进制中有几个数不同。

    taozi的暴力。

    #include<stdio.h>
    int main()
    {
        __int64 a,b;
        while(scanf("%I64d%I64d",&a,&b)!=EOF,a||b)
        {
            int c[65]={0},d[65]={0};
            int c1=64,d1=64;
            while(a)
            {
                c[c1--]=a%2;
                a/=2;
            }
            while(b)
            {
                d[d1--]=b%2;
                b/=2;
            }
            int ans=0;
            for(int i=0;i<=64;i++)
                if(c[i]!=d[i])
                    ans++;
            printf("%d
    ",ans);
        }
        return 0;
    }
    D.cpp O(64)

    zenghuan_的位运算。

    1. A & B,得到的结果C中的1的位表明了A和B中相同的位都是1的位;
    2. A | B, 得到的结果D中的1的位表明了A和B在该位至少有一个为1的位,包含了A 与 B 都是1的位数,
    经过前两步的位运算,,C 中1的位表明了A 和 B在该位都是1,D中为0的位表明了A 和 B 在该位都是0 ,所以进行第三步。
    3. C ^ D,E 中为1的位表明了A 和 B不同的位。

    #include<bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        long long a,b,c,d,e;
        while(cin>>a>>b)
        {
            if(a==0&&b==0)break;
            c=a&b;
            d=a|b;
            e=a^b;
            long long sum=0;
            while(e!=0)
            {
                e=((e-1)&e);
                sum++;
            }
            cout<<sum<<endl;
        }
        return 0;
    }
    D.cpp O(64/8)

    E.2938

    m*n的矩阵,绕圈填。

    模拟。

    #include <bits/stdc++.h>
    using namespace std;
    int number;
    int n,m,jishu;
    char arr[55][55];
    int main()
    {
        cin>>n>>m;
        char s='A';
        int t=n/2+n%2;
            for(int i=0;i<t;i++){
                for(int j=i;j<=m-i-1&&jishu<n*m;j++){
                    arr[i][j]=s++;
                    jishu++;
                    if(s=='Z'+1) s='A';
                }
                for(int j=i+1;j<=n-i-1&&jishu<n*m;j++){
                    arr[j][m-i-1]=s++;
                    jishu++;
                    if(s=='Z'+1) s='A';
                }
                for(int j=m-i-2;j>=i&&jishu<n*m;j--){
                    arr[n-i-1][j]=s++;
                    jishu++;
                    if(s=='Z'+1) s='A';
                }
                for(int j=n-i-2;j>=i+1&&jishu<n*m;j--){
                    arr[j][i]=s++;
                    jishu++;
                    if(s=='Z'+1) s='A';
                }
            }
            for(int i=0;i<n;i++)
            for(int j=0;j<m;j++){
                cout << "   " << arr[i][j];
                if(j==m-1) cout << endl;
            }
            return 0;
    }
    E.cpp

    F.2763

    求(0! + 1! + 2! + 3! + 4! + ... + n!)%m。

    思维,首先n>m的部分都是0,1!%m和2!%m那么根据乘法的同余2!=1%m*2%m。

    #include<stdio.h>
    #define ll __int64
    int main()
    {
        int t;
        char n[105];
        scanf("%d",&t);
        while(t--)
        {
            ll N=0,M;
            scanf("%s%I64d",n,&M);
            for(int i=0;n[i];i++)
            {
                if(N>=M){N=M;break;}
                N=N*10+n[i]-'0';
            }
            ll ans=1,sum=1;
            for(int i=1;i<=N;i++)
                sum=(sum+ans*i%M)%M,ans=ans*i%M;
            printf("%I64d
    ",sum%M);
        }
        return 0;
    }
    F.cpp

    G.4764

    一个n×n的正方形,现在你在正方形的左下角,每次你可以顺时针走n+1单元的距离,求多少次之后你可以回到起点。

    找规律。

    #include<stdio.h>
    int main(){
        __int64 n,s;
        while(scanf("%I64d",&n)!=EOF){
            if(n%2){
                if((n+1)%4) s=2*n+1;
                else s=n+1;
            }
            else s=4*n+1;
            printf("%I64d
    ",s);
        }
        return 0;
    }
    G.cpp

    H.4781

    ax3+bx2+cx+d=0 ,给出(a,b,c,d)求x。

    暴力,由于根的范围很小,并且保留两位小数。注意在比较double会有误差,要取fabs<=1e-5。

    #include<stdio.h>
    #include<math.h>
    int main(){
        float a,b,c,d;
        scanf("%f%f%f%f",&a,&b,&c,&d);
        int i,f=1;
        for(i=-10000;i<=10000;i++){
            float x=i*1.0/100;
            if(fabs(a*x*x*x+b*x*x+c*x+d)<=1e-5){
                if(f){
                    printf("%.2f",x);f=0;
                }
                else printf(" %.2f",x);
            }
        }
        printf("
    ");
    }
    H.cpp

    I.2955

    n个点m条无向边,问至少加多少条边使得全图连通。

    并查集模板题。

    #include<bits/stdc++.h>
    using namespace std;
    int F[101],T;
    int Find(int x)
    {
        return F[x]==x? x:Find(F[x]);
    }
    int main(){
        int N,M,A,B;
        while(cin>>N>>M)
        {
            for(int i=1;i<=N;i++)
                F[i]=i;
            T=N-1;
            for(int i=0;i<M;i++)
            {
                cin>>A>>B;
                int x=Find(A);
                int y=Find(B);
                if(x!=y)
                {
                    F[x]=y;
                    T--;
                }
            }
            cout<<T<<endl;
        }
    }
    I.cpp

    J.3207

    n个点m条无向边,问C到D的最短路。

    floyd最短路模板题,这里用dijstra也行。

    #include<bits/stdc++.h>
    using namespace std;
    
    int n,m,ss[1005][1005];
    void dij(int a,int b)
    {
        int dis[n+1][n+1];
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                dis[i][j]=ss[i][j];
        for(int k=1;k<=n;k++)
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                if(dis[i][j]>dis[k][j]+dis[i][k])
                dis[i][j]=dis[k][j]+dis[i][k];
        if(dis[a][b]==0x3f3f3f3f)cout<<"NO"<<endl;
        else cout<<dis[a][b]<<endl;
    }
    int main()
    {
        int a,b,c;
        cin>>n>>m;
        memset(ss,0x3f,sizeof(ss));
        for(int i=0;i<m;i++)
        {
            cin>>a>>b>>c;
            ss[a][b]=ss[b][a]=c;
        }
        while(cin>>a>>b)
        {
            if(a==0&&b==0)break;
            dij(a,b);
        }
        return 0;
    }
    J.cpp
  • 相关阅读:
    简单实现vue列表点击某个高亮显示
    vue中子组件直接修改父组件prop属性bug
    Java基础——关于接口和抽象类的几道练习题
    Eclipse中导入外部jar包步骤
    Java基础——关于jar包的知识
    Java基础——关于访问权限的一道例题
    Java基础——抽象类和接口
    Java基础——多态
    Java基础——继承
    三个案例,解读静态代码块和构造代码块
  • 原文地址:https://www.cnblogs.com/taozi1115402474/p/10886969.html
Copyright © 2020-2023  润新知