zoukankan      html  css  js  c++  java
  • Zut_round 7

    题目链接

    思路:一共有N个摊位,C头牛,将N个摊位序号排一下序(下标从1开始),第一头牛肯定在下标为1的摊位上。则二分取 mid(两头牛之间最大的最小距离-即答案),从下标2开始遍历N个摊位,若摊位序号减去前一个放牛的摊位序号temp大于等于mid,则将一头牛放进此摊位,用此mid可以放牛的总数量sum加1。遍历结束,若sum>=C,则左边界l=mid+1,否则右边界r=mid-1。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int qs=1e5+7;
     5 const int inf=0x3f3f3f3f;
     6 ll A[qs];
     7 ll n,m;
     8 int main()
     9 {
    10     ll i,j,k,x,y;
    11     scanf("%lld%lld",&n,&m);
    12     for(i=1;i<=n;++i)     scanf("%lld",&A[i]);
    13     sort(A+1,A+1+n);
    14     ll l=0,r=A[n]-A[1];    
    15     ll mid;
    16     while(l<=r)                        //l肯定小于等于r 
    17     {
    18         ll sum=1;
    19         x=1;                        //x记录前一个牛放的位置的下标 
    20         ll temp=A[x];                //temp记录前一个牛放的位置的序号 
    21         mid=(l+r)/2;                //取中间值mid 
    22         while(sum<m)
    23         {
    24             for(i=x+1;i<=n;++i) {
    25                 if(A[i]-temp>=mid)         
    26                 {
    27                     sum++;  temp=A[i];      //将牛放到此处,可放置的牛数量加1,temp,x记录 
    28                     x=i;    break;
    29                 }    
    30             } 
    31             if(i>n) break;
    32         }
    33         if(sum<m) r=mid-1;
    34         else l=mid+1;
    35     //    printf("r=%lld l=%lld
    ",r,l);
    36     }
    37     mid=(l+r)/2;
    38 //    printf("r=%lld l=%lld
    ",r,l);
    39     cout<<mid<<endl;
    40     return 0;
    41 }
    View Code

    B 题目链接

    思路:二分取删除次数mid,根据给的删除顺序依次删除原序列 s 中的字符(注意下标),判断删除mid次后的s字符串子序列是否包含要表示的字符串S即可

    //刚开始一直以为这样遍历数组会超时没敢写2333

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int qs=2e5+7;
     5 const int inf=0x3f3f3f3f;
     6 ll A[qs];
     7 ll B[qs];
     8 map<ll,ll> mp;
     9 vector<int> v,c;
    10 bool u[qs];
    11 int main()
    12 {
    13     int i,j,k;
    14     string s,S;
    15     cin>>s;
    16     cin>>S;
    17     int n=s.size();                    //n是s的长度 
    18     for(i=0;i<n;++i) cin>>A[i];     
    19     int L=S.size();                    //L是S的长度 
    20     int l=0,r=n-L;
    21     int mid;
    22     while(l<=r)
    23     {
    24         for(i=0;i<=n;++i) u[i]=true;        //每次循环将每个下标标记为没用过 (true) 
    25         mid=(l+r)/2;
    26         int flag=0;
    27         for(i=0;i<mid;++i)
    28         u[A[i]-1]=false;                    //将需要删除的下标标为用过(false) 
    29         j=0;
    30         for(i=0;i<n;++i)
    31         {
    32             if(!u[i]) continue;
    33             if(s[i]==S[j]) j++;
    34             if(j>=L)                         //表示s子序列中存在S 
    35             {
    36             flag=1;     break;
    37             }
    38         }
    39     //    printf("l=%d  r=%d
    ",l,r);
    40         if(flag) l=mid+1;
    41         else r=mid-1;
    42     }
    43     mid=(l+r)/2;
    44     cout<<mid<<endl;
    45     return 0;
    46 }
    View Code

    D 题目链接

    思路:从高为h处开始,雪球重量加此处的高度。到有石头处时,重量先增加此处高度,再减去石头的重量,若为负数则变为0。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 ll n,m;
     5 int main()
     6 {
     7     ll i,j,k,x,y;
     8     cin>>n>>m;
     9     cin>>j>>k;
    10     cin>>x>>y;
    11     ll as=0;
    12     for(i=m;i>=0;--i)
    13     {
    14         n+=i;
    15         if(i==k)n-=j;
    16         if(i==y)n-=x;             
    17         n=max(as,n);       //n不可能为负数 
    18     }
    19     cout<<n<<endl;
    20     return 0;
    21 }
    View Code

    E 题目链接

    思路:当x和y的差值为0或1时,所包含的方形是最优的,所以x y逐渐增加判断是否大于等于n即可 //刚开始没读清题,以为要x y恰好表示n个方形qwq

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int qs=1e5+7;
     5 const int inf=0x3f3f3f3f;
     6 ll n,m;
     7 int main()
     8 {
     9     cin>>n;
    10     ll x=1,y=1;
    11     while(x*y<n)
    12     {
    13         if(x>y) y++;
    14         else x++;
    15     }
    16     ll ans=x+y;
    17     cout<<ans;
    18     return 0;
    19 }
    View Code

    F 题目链接

    思路:?可以删减或保留前一个字母。* 可以删减、保留或复制多次前一个字母。遍历字符串s,求出字母数量num, ? 数量num1, * 数量num2。

    若num<k,则字母数量需要增加。若num2=0,是不可能的。若num2>0,则只需找到第一个*的位置,将它前一个字母复制k-num次。

    若num<k,则字母数量需要减少。若k+num1+num2<num,是不可能的。否则每遇到'?'或'*'都将前一个字母删除,直到删除num-k次。

    若num=k,字母数量不变。提取字母部分即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int qs=1e5+7;
     5 const int inf=0x3f3f3f3f;
     6 ll n,m;
     7 int main()
     8 {
     9     int i,j,k;
    10     string s,ss="";
    11     cin>>s;
    12     cin>>k;
    13     int l=s.size();
    14     int num=0,num1=0,num2=0;
    15     for(i=0;i<l;++i)
    16     {
    17         if(s[i]=='?')  num1++;
    18         else if(s[i]=='*') num2++;
    19         else num++;
    20     }
    21 //    printf("s=%d
     num=%d
    ",l,num);
    22     int flag=1;
    23     if(num<k)
    24     {
    25         int fg=1;
    26         if(num2==0) flag=0;
    27         else{
    28             for(i=0;i<l;++i)
    29             {
    30                 if(s[i]>='a'&&s[i]<='z')    ss+=s[i];            
    31                 else if(s[i]=='*'&&fg)        //将前一个字母复制k-num次 
    32                 {
    33                     for(j=1;j<=k-num;++j)
    34                     ss+=s[i-1];
    35                     fg=0;
    36                 }
    37             }
    38         }
    39     }
    40     else if(num>k)
    41     {
    42         int sum=0;
    43         if(num1+num2+k<num) flag=0;
    44         else
    45         {
    46             for(i=0;i<l;++i)                    //模拟删除操作 
    47             {
    48                 if(s[i]=='*'||s[i]=='?') continue;
    49                 if(s[i+1]!='*'&&s[i+1]!='?') ss+=s[i];    //若一个字母后是字母,不能删除 
    50                 else sum++;    
    51                 if(sum==num-k) break;            //删除次数够了,结束循环 
    52             }
    53             for(j=i+1;j<l;++j)
    54             if(s[j]!='*'&&s[j]!='?')ss+=s[j];     //将剩下的字母放到新的字符串里 
    55         }
    56     }
    57     else {
    58         for(i=0;i<l;++i)
    59         if(s[i]!='?'&&s[i]!='*') ss+=s[i];
    60     }
    61 //    printf("ss=%d
    ",ss.size());
    62     if(flag) cout<<ss<<endl;
    63     else cout<<"Impossible";
    64     return 0;
    65 }
    View Code
  • 相关阅读:
    C#中 File,Directory,FileInfo,DirectoryInfo区别与应用
    C#中设置开机自动运行和关机
    C# 线程手册 第三章 使用线程 小心死锁
    C# WinForm判断Win7下是否是管理员身份运行
    C#应用MemoryStream提高File读取速度
    CodeforcesDouble Profiles
    SRM533 D1 L1
    SRM532 D1 L2
    SRM533 D2 L3
    次小生成树 | 割点 | 割边
  • 原文地址:https://www.cnblogs.com/Suki-Sugar/p/12739459.html
Copyright © 2011-2022 走看看