• 牛客练习赛7


    骰⼦的游戏
    时间限制:C/C++ 1秒,其他语言2秒
    空间限制:C/C++ 32768K,其他语言65536K
    64bit IO Format: %lld

    题目描述

        在Alice和Bob面前的是两个骰子,上面分别写了六个数字。

        Alice和Bob轮流丢掷骰子,Alice选择第一个骰子,而Bob选择第二个,如果谁投掷出的数更大,谁就可以获胜。

        现在给定这两个骰子上的6个数字,你需要回答是Alice获胜几率更大,还是Bob获胜几率更大。(请注意获胜几率相同的情况)

     

    输入描述:

    第一行一个数T,表示数据个数。
    接下来的每一组数据一共有2行,每一行有6个正整数,第一行是第一个骰子上的6个数,第二行是第二个骰子上的6个数。

    输出描述:

    如果Alice获胜几率更大,你需要输出Alice;
    如果Bob获胜几率更大,你需要输出Bob;
    如果获胜几率一样大,你需要输出Tie。
    示例1

    输入

    2
    3 3 3 3 3 3
    1 1 4 4 4 4
    1 2 3 4 5 6
    6 5 4 3 2 1

    输出

    Bob
    Tie

    说明

    第一个数据中,Alice有三分之一几率获胜,Bob有三分之二几率获胜;
    第二个数据中,Alice和Bob的骰子完全一致,所以获胜几率一样大。

    备注:

    对于30%的数据,1 ≤ T ≤ 10。

    对于60%的数据,1 ≤ T ≤ 1000。

    对于100%的数据,1 ≤ T ≤ 10^5,所有输入的数均 ≤ 10^7。

    直接比较大小就可以了

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        int n,a[10],b[10];
        scanf("%d",&n);
        while(n--)
        {
            for(int i=0; i<6; i++)
                scanf("%d",&a[i]);
            for(int i=0; i<6; i++)
                scanf("%d",&b[i]);
            int s=0,t=0;
            for(int i=0; i<6; i++)
                for(int j=0; j<6; j++)
                {
                    if(a[i]>b[j])s++;
                    if(a[i]<b[j])t++;
                }
            if(s==t)puts("Tie");
            else if(s>t)puts("Alice");
            else puts("Bob");
     
        }
        return 0;
    }

     以下代码适合a,b数组特别大的时候

    nlogn解决这个a数组大于b数组的个数,无法更快解决吧,感觉两个指针可以把有序数组这个优化下

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        int n,a[10],b[10];
        scanf("%d",&n);
        while(n--)
        {
            for(int i=0; i<6; i++)
                scanf("%d",&a[i]);
            for(int i=0; i<6; i++)
                scanf("%d",&b[i]);
            sort(a,a+6);
            sort(b,b+6);
            int s=0,t=0;
            for(int i=0;i<6;i++)
                s+=lower_bound(a,a+6,b[i])-a;
            for(int i=0;i<6;i++)
                t+=lower_bound(b,b+6,a[i])-b;
            if(s==t)puts("Tie");
            else if(s<t)puts("Alice");
            else puts("Bob");
        }
        return 0;
    }

    我想的尺取贪心写不大出来,感觉二分够了,顶多加个离散化

    购物
    时间限制:C/C++ 1秒,其他语言2秒
    空间限制:C/C++ 32768K,其他语言65536K
    64bit IO Format: %lld

    题目描述

    在遥远的东方,有一家糖果专卖店。
    这家糖果店将会在每天出售一些糖果,它每天都会生产出m个糖果,第i天的第j个糖果价格为C[i][j]元。
    现在的你想要在接下来的n天去糖果店进行选购,你每天可以买多个糖果,也可以选择不买糖果,但是最多买m个。(因为最多只生产m个)买来糖果以后,你可以选择吃掉糖果或者留着之后再吃。糖果不会过期,你需要保证这n天中每天你都能吃到至少一个糖果。
    这家店的老板看你经常去光顾这家店,感到非常生气。(因为他不能好好睡觉了)于是他会额外的要求你支付点钱。具体来说,你在某一天购买了 k 个糖果,那么你在这一天需要额外支付 k2 的费用。

    那么问题来了,你最少需要多少钱才能达成自己的目的呢?

     

    输入描述:

    第一行两个正整数n和m,分别表示天数以及糖果店每天生产的糖果数量。
    接下来n行(第2行到第n+1行),每行m个正整数,第x+1行的第y个正整数表示第x天的第y个糖果的费用。

    输出描述:

    输出只有一个正整数,表示你需要支付的最小费用。
    示例1

    输入

    3 2 
    1 1
    100 100 
    10000 10000

    输出

    107
    示例2

    输入

    5 5
    1 2 3 4 5
    2 3 4 5 1 
    3 4 5 1 2 
    4 5 1 2 3 
    5 1 2 3 4

    输出

    10

    备注:

    对于100%的数据,1 ≤ n, m ≤ 300 , 所有输入的数均 ≤ 106。

    dp,前i天买x个最小花费

    #include<bits/stdc++.h>
    using namespace std;
    vector<int>V[305];
    int dp[305][305],a[305][305];
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                int x;
                scanf("%d",&x);
                V[i].push_back(x);
            }
            sort(V[i].begin(),V[i].end());
            for(int j=1; j<=m; j++)
                a[i][j]=a[i][j-1]+V[i][j-1];
        }
        memset(dp,-1,sizeof dp);
        dp[0][0]=0;
        for(int i=1; i<=n; i++)
            for(int j=i; j<=n; j++)
            {
                for(int k=0; k<=j&&k<=m; k++)
                {
                    if(dp[i-1][j-k]!=-1)
                    {
                        if(dp[i][j]!=-1)dp[i][j]=min(dp[i-1][j-k]+a[i][k]+k*k,dp[i][j]);
                        else dp[i][j]=dp[i-1][j-k]+a[i][k]+k*k;
                    }
                }
            }
        printf("%d",dp[n][n]);
        return 0;
    }
    珂朵莉的数列
    时间限制:C/C++ 2秒,其他语言4秒
    空间限制:C/C++ 131072K,其他语言262144K
    64bit IO Format: %lld

    题目描述

    珂朵莉给了你一个序列,有个子区间,求出她们各自的逆序对个数,然后加起来输出

    输入描述:

    第一行一个数 n 表示这个序列 a 的长度

    之后一行 n 个数,第i个数表示ai

    输出描述:

    输出一行一个数表示答案
    示例1

    输入

    10
    1 10 8 5 6 2 3 9 4 7

    输出

    270
    示例2

    输入

    20
    6 0 4 5 8 8 0 6 6 1 0 4 6 6 0 0 7 2 0 5

    输出

    3481

    备注:

    对于100%的数据,n <=
    1000000 ,0 <= 序列中每个数 <= 1000000000

    树状数组+二维pair算贡献去求

    但是爆了ll

    #include<bits/stdc++.h>
    using namespace std;;
    typedef long long ll;
    const int N=1e6+5;
    int n,cnt=1,a[N];
    pair<int,int> t[N];
    ll c[N];
    string add(string s1,string s2){
        string s;
        int len1,len2;
        len1=s1.size()-1; len2=s2.size()-1;
        int i=0,f=0;
        while(len1>-1&&len2>-1){
            int sum=f+(s1[len1--]-'0')+(s2[len2--]-'0');
            s+=sum%10+'0';
            f=sum/10;
        }
        while(len1>-1){
            int sum=f+(s1[len1--]-'0');
            s+=sum%10+'0';
            f=sum/10;
        }
        while(len2>-1){
            int sum=f+(s2[len2--]-'0');
            s+=sum%10+'0';
            f=sum/10;
        }
        if(f) s+='0'+f;
        reverse(s.begin(),s.end());
        return s;
    }
    void add(int k,int x)
    {
        while(k>=1)
        {
            c[k]+=x;
            k-=(k&-k);
        }
    }
    ll query(int k)
    {
        ll ans=0;
        while(k<=cnt)
        {
            ans+=c[k];
            k+=(k&-k);
        }
        return ans;
    }
    void solve()
    {
        string ans="0";
        for(int i=1; i<=n; i++)
        {
            ll x=query(a[i]+1)*1LL*(n-i+1);
            string c1="";
            if(x==0)c1+="0";
            while(x)
            {
               c1+=x%10+'0';
               x=x/10;
            }
            reverse(c1.begin(),c1.end());
            ans=add(ans,c1);
            add(a[i],i);
        }
        cout<<ans<<endl;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
            t[i]=make_pair(a[i],i);
        }
        sort(t+1,t+n+1);
        for(int i=1; i<=n; i++)
        {
            if(t[i-1].first!=t[i].first)
            {
                cnt++;
            }
            a[t[i].second]=cnt;
        }
        solve();
        return 0;
    }

    __int128写法

    #include<bits/stdc++.h>
    using namespace std;;
    typedef long long ll;
    const int N=1e6+5;
    int n,cnt=1,a[N];
    pair<int,int> t[N];
    ll c[N];
    void print(__int128 x)
    {
        if (x==0) return;
        if (x) print(x/10);
        putchar(x%10+'0');
    }
    void add(int k,int x)
    {
        while(k>=1)
        {
            c[k]+=x;
            k-=(k&-k);
        }
    }
    ll query(int k)
    {
        ll ans=0;
        while(k<=cnt)
        {
            ans+=c[k];
            k+=(k&-k);
        }
        return ans;
    }
    void solve()
    {
        __int128 ans=0;
        for(int i=1; i<=n; i++)
        {
            ans+=query(a[i]+1)*1LL*(n-i+1);
            add(a[i],i);
        }
        if(ans==0)putchar('0');
        print(ans);
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
            t[i]=make_pair(a[i],i);
        }
        sort(t+1,t+n+1);
        for(int i=1; i<=n; i++)
        {
            if(t[i-1].first!=t[i].first)cnt++;
            a[t[i].second]=cnt;
        }
        solve();
        return 0;
    }
  • 相关阅读:
    “智商平平”学软件
    一个多线程示例程序的BUG修复
    金旭亮《C#面向对象程序设计》2011完整版发布
    《.NET 4.0网络开发入门之旅》7:填平缓冲区陷阱
    《.NET 4.0网络开发入门之旅》5:与Socket的“再次见面”
    《.NET 4.0网络开发入门之旅》6:“麻烦”的数据缓冲区
    软件天才与技术民工
    .NET 4.0 技术亮点剖析——在中科院计算所的讲座PPT及源码下载
    C#实现程序的开机启动
    C#获取当前时间、日期
  • 原文地址:https://www.cnblogs.com/BobHuang/p/7955186.html
Copyright © 2020-2023  润新知