zoukankan      html  css  js  c++  java
  • 2018 ACM-ICPC亚洲区域赛(青岛)

    Problem C---zoj 4060 Flippy Sequence

    解题思路:要求进行两次操作,每次操作选择一个区间,问将s串变成t串中所选的两个区间构成的4元组有多少个。做法:找出s串与t串不同块的个数,然后做个简单的判断即可。

    AC代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 const int maxn=1e6+5;
     5 int T,n,cnt,answer;char s1[maxn],s2[maxn];
     6 int main(){
     7     while(~scanf("%d",&T)){
     8         while(T--){
     9             scanf("%d %s %s",&n,s1,s2);cnt=0;
    10             for(int i=0;i<n;++i)//统计s串与t串不同块的个数
    11                 if((i==0&&s1[i]!=s2[i])||(i>0&&s1[i-1]==s2[i-1]&&s1[i]!=s2[i]))cnt++;
    12             if(!cnt)answer=n*(n+1)/2;//全部相同:1+...+n
    13             else if(cnt==1)answer=2*(n-1);//只有一个不同块,①不同和不同进行反转,②不同和相同进行反转
    14             else if(cnt==2)answer=6;//有两个不同块,三种操作,答案肯定为6
    15             else answer=0;//至少有3个不同块,无法实现2次操作,答案只能为0
    16             printf("%d
    ",answer);
    17         }
    18     }
    19     return 0;
    20 }

    Problem E---zoj 4062 Plants vs. Zombies

    (补)解题思路:典型的最大化最小值,二分解法再加个贪心,详解看代码。

    AC代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 const int maxn=1e5+5;
     5 int T,n;LL m,l,r,mid,a[maxn],d[maxn];
     6 bool check(LL x){
     7     ///二分总防御值,对于固定的防御值x,显然花园里的每个植物都要不小于x,因此贪心地从左往右寻找每一个防御值小于x的植物,对它和它右侧的植物反复浇水。
     8     LL step=0;
     9     for(int i=0;i<n;++i)d[i]=x/a[i]+(x%a[i]?1LL:0LL);///计算每个至少需要浇水的次数
    10     for(int i=0;i<n;++i){
    11         if(!d[i]){
    12             if(i!=n-1)step++;///如果最后一棵植物需要浇水的次数为0,说明其防御值不小于当前x,则无需计数
    13         }else{
    14             step+=d[i]*2LL-1LL;///累加从i-1走到i这1步+浇完第i棵植物后花费的总步数为2*d[i]-1
    15             d[i+1]-=(d[i]-1LL);///第i+1棵植物需要浇水的次数要减去(d[i]-1)
    16             if(d[i+1]<0)d[i+1]=0LL;///如果d[i+1]<0,说明下一棵植物的防御值早已大于x,下次只需给它浇一次水(贪心向右移动一步)即可
    17         }
    18         if(step>m)return false;///如果所走步数超过m,则直接返回0,找较小的答案x
    19     }
    20     return true;
    21 }
    22 int main(){
    23     while(~scanf("%d",&T)){
    24         while(T--){
    25             scanf("%d%lld",&n,&m);
    26             for(int i=0;i<n;++i)scanf("%lld",&a[i]);
    27             l=1LL,r=1e18;
    28             while(l<=r){///[l,r],退出条件是l>r,即l-1==r
    29                 mid=(l+r)>>1;
    30                 if(check(mid))l=mid+1LL;///还有满足条件的最小值,继续最大化
    31                 else r=mid-1LL;///不满足条件,往左找
    32                 ///cout<<l<<' '<<r<<endl;
    33             }
    34             printf("%lld
    ",l-1);///l-1相当于r,因为l会不断被最大化,直到超过r,则可以取l-1或者r就是最大化最小值答案
    35         }
    36     }
    37     return 0;
    38 }

    Problem J---zoj 4067 Books

    解题思路:没有理解好题意,因此赛场上丧心病狂调了2小时的bug,罚时巨多QWQ,其实就是个简单的贪心=_=。题意:DreamGrid带的钱会在1~n本书中从前往后进行挑选,如果当前剩余的钱不小于第i本书的价格,那么他就一定会买这本书,并且用剩余的钱减去第i本书的价格,直到买完m本书,否则就跳过不买第i本书籍。首先要明确的一点:从其往后有序挑选!!!分三种情况:①当m==n时,显然为"Richman";②当m<cnt_0时,此时可以买比m多的书籍,显然为"Impossible";③当m>cnt_0时,首先肯定会挑选cnt_0个价格为0的书籍,然后从前往后在价格不为0的书籍里面贪心挑选(m-cnt_0)本书籍,再加上后面不为0的最小价格-1即为DreamGrid可带的最多零钱。

    AC代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;LL ans;//注意用long long
     4 const int inf=0x3f3f3f3f;
     5 const int maxn=1e5+5;
     6 int T,n,m,cnt_0,pos,mina,s[maxn];
     7 int main(){
     8     while(cin>>T){
     9         while(T--){
    10             cin>>n>>m;cnt_0=0;
    11             for(int i=0;i<n;++i)cin>>s[i],cnt_0+=s[i]?0:1;//统计0的个数
    12             if(m==n)puts("Richman");
    13             else if(cnt_0>m)puts("Impossible");//如果0的个数大于m,肯定可以买更多的书籍,显然此时为不可能
    14             else{
    15                 m-=cnt_0,mina=inf,pos=0,ans=0;//m为剩下要挑选的本数
    16                 while(m)s[pos]?ans+=s[pos++],m--:pos++;//贪心选择价格不为0的m本,然后在后面选择一本最小的价格(不为0)-1加上来即为最优答案
    17                 for(int i=pos;i<n;++i)//从连续选择pos个不为0的数后,再从后面选择不为0的最小价格
    18                     if(s[i])mina=min(mina,s[i]);
    19                 cout<<(ans+=mina-1)<<endl;
    20             }
    21         }
    22     }
    23     return 0;
    24 }

    Problem M---zoj 4070 Function and Function

    解题思路:签道题,注意:输入的x为0时要单独考虑。

    AC代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 int T,x,k,s[]={1,0,0,0,1,0,1,0,2,1};
     5 int g(int y){
     6     int ans=0;
     7     while(y){ans+=s[y%10];y/=10;}
     8     return ans;
     9 }
    10 int main(){
    11     while(~scanf("%d",&T)){
    12         while(T--){
    13             scanf("%d%d",&x,&k);
    14             if(!x)x=k&1?1:0;//x为0要单独考虑
    15             else{
    16                 for(int i=1;i<=k&&x;++i){
    17                     x=g(x);
    18                     if(!x){x=(k-i)&1?1:0;break;}
    19                 }
    20             }
    21             printf("%d
    ",x);
    22         }
    23     }
    24     return 0;
    25 }
  • 相关阅读:
    [APM] OneAPM 云监控部署与试用体验
    Elastic Stack 安装
    xBIM 综合使用案例与 ASP.NET MVC 集成(一)
    JQuery DataTables Selected Row
    力导向图Demo
    WPF ViewModelLocator
    Syncfusion SfDataGrid 导出Excel
    HTML Table to Json
    .net core 2.0 虚拟目录下载 Android Apk 等文件
    在BootStrap的modal中使用Select2
  • 原文地址:https://www.cnblogs.com/acgoto/p/9916105.html
Copyright © 2011-2022 走看看