• Codeforces Round #570 (Div. 3) B. Equalize Prices、C. Computer Game、D. Candy Box (easy version)、E. Subsequences (easy version)


    B题题意:

    给你n个物品的价格,你需要找出来一个值b,使得每一个物品与这个b的差值的绝对值小于k。找到最大的b输出,如果找不到,那就输出-1

    题解:

    很简单嘛,找到上下限直接二分。下限就是所有物品中最小的价格。上限就是所有物品中最大价格加上k

    代码:

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<map>
     6 #include<math.h>
     7 using namespace std;
     8 typedef long long ll;
     9 const int maxn=1e5+5;
    10 const int mod=26;
    11 const int INF=0x3f3f3f3f;
    12 const int block=300;
    13 int main()
    14 {
    15     int t;
    16     scanf("%d",&t);
    17     while(t--)
    18     {
    19         int b,n,k,minn=INF,maxx=0;
    20         scanf("%d%d",&n,&k);
    21         for(int i=1;i<=n;++i)
    22         {
    23             scanf("%d",&b);
    24             minn=min(minn,b);
    25             maxx=max(maxx,b);
    26         }
    27         int mid=(minn+maxx)/2;
    28         if(mid-minn<=k && maxx-mid<=k)
    29         {
    30             int ans=mid,m,l=mid,r=maxx+k;
    31             while(l<=r)
    32             {
    33                 m=(l+r)/2;
    34                 if(m-minn<=k)
    35                 {
    36                     ans=m;
    37                     l=m+1;
    38                 }
    39                 else r=m-1;
    40             }
    41             printf("%d
    ",ans);
    42         }
    43         else printf("-1
    ");
    44     }
    45     return 0;
    46 }
    View Code

    c题题意:

    最开始有k电量,你需要玩n个回合的游戏,每一回合你可以有两个选择

    1、玩游戏,但是要消耗a电量

    2、边充电边玩,消耗b电量

    还有一个限制:如果电量小于等于a,那就不可以玩游戏;如果电量小于等于b那就不可以边充边玩

    如果玩游戏玩不了n个回合,就输出-1,否则就输出你玩游戏的次数(可不是边充边玩)

    题解:

    思路很容易想,但是就是实现难!

    你可以先n个回合都选择第二种模式来玩游戏,看电量够不够。如果不够就直接输出-1

    这里判断就可以先玩n-1个回合,看看剩下的电量大不大于b。如果大于那就证明可以玩够n个回合,否则就不可以

    因为电量必须大于b才能边充边玩

    然后就二分 选择了几次第一个选择(即消耗电量为a) ,每一次的判断都类似上面的判断方式

    还有就是要用long long

    代码:

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<map>
     6 #include<math.h>
     7 using namespace std;
     8 typedef long long ll;
     9 const int maxn=1e5+5;
    10 const int mod=26;
    11 const int INF=0x3f3f3f3f;
    12 const int block=300;
    13 ll k,n,a,b;
    14 bool check(ll x)
    15 {
    16     ll cha,ci;
    17     if(x)
    18     {
    19         if(k-(a*(x-1))<=a) return 0;
    20     }
    21 
    22     cha=k-a*x;
    23     ci=n-x;
    24     if(ci==0) return 1;
    25     if(cha-(b*(ci-1))<=b) return 0;
    26     else return 1;
    27 }
    28 int main()
    29 {
    30     ll t;
    31     cin>>t;
    32     while(t--)
    33     {
    34         cin>>k>>n>>a>>b;
    35         if(k-(b*(n-1))<=b)
    36         {
    37             printf("-1
    ");
    38             continue;
    39         }
    40         else
    41         {
    42             ll l=0,r=n,m,ans=0;
    43             while(l<=r)
    44             {
    45                 m=(l+r)>>1;
    46                 if(check(m))
    47                 {
    48                     ans=m;
    49                     l=m+1;
    50                 }
    51                 else r=m-1;
    52             }
    53             printf("%I64d
    ",ans);
    54         }
    55     }
    56     return 0;
    57 }
    View Code

    D题题意:

    给你n个糖果,每一个糖果有一个种类,你需要用这些不同种类的糖果来弄成一个礼物

    但是这个礼物里面各 种类 糖果的数量不能相同,你需要找出来这个礼物最多能由多少糖果构成

    题解:

    你会发现,如果一种糖果的个数是n,那么它可以拿出n-1、n-2、n-3来放入礼物中

    注释+代码:

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<map>
     6 #include<math.h>
     7 using namespace std;
     8 typedef long long ll;
     9 const int maxn=2e5+5;
    10 const int mod=26;
    11 const int INF=0x3f3f3f3f;
    12 const int block=300;
    13 int v[maxn],w[maxn];
    14 int main()
    15 {
    16     int t;
    17     scanf("%d",&t);
    18     while(t--)
    19     {
    20         int n,a,maxx=0;
    21         scanf("%d",&n);
    22         for(int i=1;i<=n;++i) //这里不能用memset,要不然会超时
    23             v[i]=w[i]=0;
    24         for(int i=1;i<=n;++i)
    25         {
    26             scanf("%d",&a);
    27             w[v[a]]--;  //w是记录有多少种糖果且这种糖果的数量是v[a]
    28             v[a]++;    //v是记录每一种糖果的数量
    29             w[v[a]]++;
    30             //printf("%d %d %d
    ",a,v[a],w[v[a]]);
    31             maxx=max(maxx,v[a]);
    32         }
    33         int ans=0,sum=0;//printf("%d**
    ",maxx);
    34         for(int i=maxx;i>0;--i)
    35         {
    36 
    37             ans+=w[i];
    38             if(ans>0)  //如果你有一种糖果数量是5,此时这个可以来拿出来4个,来填充  
    39  //礼物,也可以都拿出来,这要看有没有其他种类的糖果也有这个数量个糖果
    40                 sum+=i,ans--;
    41         }
    42         printf("%d
    ",sum);
    43     }
    44     return 0;
    45 }
    View Code

    E题题意:

    给你一个长为n的字符串,你需要从中找出来k个不重复的子序列(注意是子序列而不是子串。子序列不需要连续,可以再原字符串中间删除字母)。如果可以找到输出你删除的总字母个数(你要是这个值尽可能地小),如果不能输出-1

    题解:

    如果直接暴力dfs,那就相当于2^100,肯定会超时,那我们注意到k的值比较小,所有我们就可以找到k个子序列就可以了。又因为题目有要求输出的值尽量小。所以我们就可以按删除字符从小到大来枚举

    我这里采用set去重

    代码:

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<map>
     6 #include<math.h>
     7 #include<set>
     8 #include<queue>
     9 using namespace std;
    10 typedef long long ll;
    11 const int maxn=2e5+5;
    12 const int mod=26;
    13 const int INF=0x3f3f3f3f;
    14 const int block=300;
    15 
    16 int main()
    17 {
    18     int n,k,ans=0;
    19     queue<string>r;
    20     set<string>str;
    21     string s;
    22     cin>>n>>k;
    23     cin>>s;
    24     r.push(s);
    25     str.insert(s);
    26     while(!r.empty() && str.size()<k)
    27     {
    28         string ss=r.front();
    29         r.pop();
    30         int len=ss.size();
    31         //printf("%d %d**
    ",ss.length(),ss.size());
    32         for(int i=0;i<len;++i)
    33         {
    34             string fresh=ss;
    35             fresh.erase(i,1);
    36             //cout<<fresh<<"**"<<endl;
    37             if(!str.count(fresh) && str.size()<k)
    38             {
    39                 //cout<<1<<endl;
    40                 r.push(fresh);
    41                 str.insert(fresh);
    42                 ans+=n-fresh.size();
    43                 if(str.size()==k) break;
    44             }
    45         }
    46     }
    47     if(str.size()<k)
    48         printf("-1
    ");
    49     else printf("%d
    ",ans);
    50 }
  • 相关阅读:
    灰度直方算法 C++
    三国谋士智商前20名
    get the runing time of C++ console program.
    支持向量机 support vector machine
    Typical sentences in SCI papers
    C++调用GDAL库读取并输出tif文件,并计算斑块面积输出景观指数:CSD
    通过管理工具对服务器进行远程管理
    Connected_Component Labelling(联通区域标记算法) C++实现
    Fragstats景观分析研究
    Install GDAL in OpenSUSE 12.3 Linux
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/11555285.html
Copyright © 2020-2023  润新知