zoukankan      html  css  js  c++  java
  • 2020牛客寒假算法基础集训营2 题解

    A-做游戏(思维)

    ans=min(A,X)+min(B,Y)+min(C,Z)

    #include<iostream>
    #include<algorithm>
     using namespace std;
     typedef long long ll;
     ll min(ll a,ll b){ if(a>b) return b;return a;}
     ll a[3],b[3];
     int main()
     {
         for(int i=0;i<3;i++)    scanf("%lld",&a[i]);
         for(int i=0;i<3;i++)    scanf("%lld",&b[i]);
         ll ans=min(a[0],b[1])+min(a[1],b[2])+min(a[2],b[0]);
         cout<<ans<<endl;
      } 

    B-排数字(思维题)

    最佳的排列方法为616161616.....,设字符串中1的个数为x,6的个数为y,当y≥2的时候ans=min(y-1,x)

    #include<iostream>
    #include<algorithm>
     using namespace std;
     const int maxn=2e5+10;
     char s[maxn];
     int main()
     {
         int n,x=0,y=0;
         scanf("%d%s",&n,s);
         for(int i=0;i<n;i++){
             if(s[i]=='6')    x++;
            else if(s[i]=='1')    y++; 
         }
        int ans=0;
        if(x>=2)    ans=min(x-1,y);
        cout<<ans<<endl;
     }
     

    G-判正误(快速幂)

    直接计算mod1e9+7意义下等式左边的值判断是否等于右边即可

    #include<iostream>
    #include<algorithm>
     using namespace std;
     typedef long long ll;
     const int mod=1e9+7;
     ll pow(ll a,ll b)
     {
         ll res=1;
         while(b){
             if(b&1)    res=(a*res)%mod;
             b>>=1;
             a*=a;
             a%=mod;
         }
        return res;
     }
     int main()
     {
         int n;
         scanf("%d",&n);
        while(n--){
            ll a,b,c,d,e,f,g;
            cin>>a>>b>>c>>d>>e>>f>>g;
            ll ans=pow(a,d)%mod;
            ans+=pow(b,e)%mod;
            ans+=pow(c,f)%mod;
            if(ans==g)    cout<<"Yes"<<endl;
            else cout<<"No"<<endl;
        }     
     }
     

     D-数三角(计算几何)

    枚举三个顶点,判断两条边的点积是否小于0即可,注意判断三点共线的情况

    #include<iostream>
    #include<algorithm>
     using namespace std;
     typedef long long ll;
     const int maxn=505;
     ll n,x[maxn],y[maxn];
     bool judge(int a,int b,int c)
     {
         if((x[a]*y[b]-x[b]*y[a]+x[b]*y[c]-x[c]*y[b]+x[c]*y[a]-x[a]*y[c])==0)    return false;
         return (x[b]-x[a])*(x[c]-x[a])+(y[b]-y[a])*(y[c]-y[a])<0;
     }
     int main()
     {
         scanf("%lld",&n);
         ll ans=0;
         for(int i=0;i<n;i++) scanf("%lld%lld",&x[i],&y[i]);
        for(int i=0;i<n;i++){
            for(int j=i+1;j<n;j++){
                for(int k=j+1;k<n;k++){
                    if(judge(i,j,k)||judge(j,k,i)||judge(k,i,j)) ans++;
                }
            }
        }
        cout<<ans<<endl;     
        return 0;
     }

     C-算概率(概率)

    设f[i][j]为做i道题对j题的概率,①当j>0时,fi,j = fi-1,j * ( 1 - p[i] ) + fi-1,j-1 * p[i] ②当j=0时,fi,j = fi-1,j * ( 1 - p[i] ) 

    #include<iostream>
    #include<algorithm>
     using namespace std;
     typedef long long ll;
     const int maxn=2005;
     const int mod=1e9+7;
     ll p[maxn],f[maxn][maxn];
     int main()
     {
         int n;
         scanf("%d",&n);
         for(int i=1;i<=n;i++)    scanf("%lld",&p[i]);
         f[0][0]=1;
         for(int i=1;i<=n;i++){
             f[i][0]=f[i-1][0]*(mod+1-p[i])%mod;
             for(int j=1;j<=n;j++)
             f[i][j]=f[i-1][j]*(mod+1-p[i])%mod+(f[i-1][j-1]*p[i])%mod;
         }
        for(int i=0;i<=n;i++)    cout<<f[n][i]%mod<<" ";
     }

     E-统计数(数学)

    对等式两边同时平方 : i + j + 2 * sqrt( i * j) =k,这样我们发现 i * j必须是完全平方数的时候才可以,因此我们枚举完全平方数,再枚举其因子数即可,每次都加2(因为 (2,8,4) 跟 (8,2,4)算两个)最后还要再减去1(减去(4,4,4)这种情况),

    #include<iostream>
    #include<algorithm>
    #include<cmath>
     using namespace std;
     int main()
     {
         int n,ans=0;
         scanf("%d",&n);
         for(int i=1;i<=sqrt(n);i++){
             for(int j=1;j<=i;j++)
                 if(i*i%j==0)    ans+=2;
             ans--;
         }
        cout<<ans<<endl;
     }

     F-拿物品(思维题,排序)

    直接按照两物品的和排序依次输出即可

    #include<iostream>
    #include<algorithm>
     using namespace std;
     const int maxn=2e5+10;
     struct node{
         int a,b,sum,pos;
     }a[maxn]; 
     int cmp(node x,node y){return x.sum>=y.sum;}
     int main()
     {
         int n;
         scanf("%d",&n);
         for(int i=1;i<=n;i++)    scanf("%d",&a[i].a),a[i].pos=i;
         for(int i=1;i<=n;i++)    scanf("%d",&a[i].b),a[i].sum=a[i].a+a[i].b;
         sort(a+1,a+1+n,cmp);
         for(int i=1;i<=n;i+=2)    cout<<a[i].pos<<" ";
         cout<<endl;
         for(int i=2;i<=n;i+=2)    cout<<a[i].pos<<" ";
     }

     H-施魔法(DP)

    先将数组排序,数组被连续的分成几段取完代价才能最小

    定义 f i为取完前i个元素的花费

    维护  的前缀最小值就能O(1)转移了。

    #include<iostream>
    #include<algorithm>
     using namespace std;
     const int maxn=3e5+7;
     int a[maxn],dp[maxn],pre,k,n;
     int main()
     {
         scanf("%d%d",&n,&k);
         for(int i=1;i<=n;i++) scanf("%d",&a[i]);
         sort(a+1,a+1+n);
         pre=-a[1];
         for(int i=1;i<k;i++)    dp[i]=2e9;
         for(int i=k;i<=n;i++){
             dp[i]=pre+a[i];
             pre=min(pre,dp[i-k+1]-a[i-k+2]);
         }
        cout<<dp[n]<<endl;
     }

    J-求函数(线段树)

    题解链接:https://www.cnblogs.com/overrate-wsj/p/12274408.html

    I-建通道(思维)

    思路:对于相同的元素,连接起来的代价为0,所以我们可以先将所有元素去重。去重之后,我们从低到高遍历每个数字的每一位(二进制意义下),找到所有数字中既有0又有1的一位,将边将在0与1之间,这样的代价肯定是最小的

    #include<iostream>
    #include<algorithm>
     using namespace std;
     typedef long long ll;
     const int maxn=2e5+10;
     ll a[maxn];
     int main()
     {
         int n;
         scanf("%d",&n);
         for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
         sort(a+1,a+1+n);
         int len=unique(a+1,a+1+n)-(a+1);
         for(int i=0;i<=30;i++){
             ll ans=1<<i;
            int x=0,y=0;
            for(int j=1;j<=len;j++){
                if((a[j]>>i)&1)    x++;
                else    y++;
            } 
            if(x&&y){
                ans*=(ll)(len-1);
                cout<<ans<<endl;
                return 0;
            }
         }
         cout<<0<<endl;
         return 0;
     }
  • 相关阅读:
    jdk版本切换
    Java开发中遇到的问题
    递归删除文件夹
    重写equals方法
    JSP基础
    js把变量转换成json数据
    myBatista批量查询和插入
    Jquery密码强度校验
    Linux配置外网访问mysql
    linux下开启、关闭、重启mysql服务命令
  • 原文地址:https://www.cnblogs.com/overrate-wsj/p/12269479.html
Copyright © 2011-2022 走看看