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\n",r,l);
36     }
37     mid=(l+r)/2;
38 //    printf("r=%lld l=%lld\n",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\n",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\n num=%d\n",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\n",ss.size());
62     if(flag) cout<<ss<<endl;
63     else cout<<"Impossible";
64     return 0;
65 }
View Code

 

posted @ 2020-04-20 18:06  Suki_Sugar  阅读(94)  评论(0编辑  收藏  举报
Live2D