zoukankan      html  css  js  c++  java
  • Codeforces Round #334 (Div. 2) C. Alternative Thinking

    题目链接:http://codeforces.com/contest/604/problem/C

    大致题意:给定一个01串以及其长度,求此串中符合形如“0101“或”101“这种01交错的序列(不必连续)的长度,并且你可以选定这个串中1段连续的子串进行反转(将0反转为1,将1反转为0),力求反转之后的串中所符合题意的序列的长度最大,并输出其长度。

    (题目中”he decides that he will flip exactly one substring—that is, take a contiguous non-empty substring of his score and change all '0's in that substring to '1's and vice versa.“ 中的 ”vice versa“的意思是”反之亦然“,英语不好没读懂,以为只能将0反转为1,WA了好几次,哭瞎)

    大致思路:

    串中如果有一处00或11这样连个在一起的,我们可以改变之前或者之后的所有数,则序列长度可以增加1。形如:1101,序列长度为3,反转成1[010],序列长度为4.

    如果有两处,则我们可以改变这两处之间所有的数,序列长度可以增加2。形如: 110100,原本序列长度为4,然后反转成1[0101]0,反转之后的序列长度为6.

    遇见000 111这样的三个连在一起的,则可以将形如”000“改为”010“,可以直接判断序列增加2

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <string>
     5 
     6 using namespace std;
     7 
     8 string arr;   //存储01串
     9 int main()
    10 {
    11     int n;
    12     cin>>n;
    13     cin>>arr;
    14     int countr=1;   //记录符合题意的序列的长度
    15     int mark=0;     //记录反转可以增加的长度
    16     
    17     char tmp=arr[0];
    18     for( int i=1; i<n; i++ )
    19     {
    20         if( arr[i]!=tmp )
    21         {
    22             countr++;
    23             tmp=arr[i];
    24         }
    25     }
    26     
    27     for( int i=0; i<n; i++ )
    28     {
    29         int flag=1;
    30         for( int j=i; j+1<n && arr[j]==arr[j+1]; j++ )
    31             flag++;
    32         if( flag>2 )   //串中有三个以上连续的1或0,直接认定序列长度可以加2
    33         {
    34             mark=2;
    35             break;
    36         }
    37         if( flag==2 && mark==0 )  //串中有一出连续的两个1或0
    38         {
    39             mark=1;
    40             i++;
    41         }
    42                                        //注意第三个if要加else if,第二个if的执行体中改变了第三个if的判断条件,会导致第二个if执行完后第三个接着就执行了        
    43         else if( flag==2 && mark==1 )  //串中有两处连续的1或0,直接认定序列长度可以加2
    44         {
    45             mark=2;
    46             break;
    47         }
    48     }
    49     countr+=mark;
    50     printf( "%d
    ",countr );
    51     return 0;
    52 }

    其实直接一层循环就可以搞定:遇见arr[i-1]==arr[i]的情况就mark++,mark加到2就break掉。我这么写加了很多逻辑判断,很丑了。

    又PS:几个if一起用的时候一定要注意其其中的逻辑,特别注意“上面if执行完后直接正好满足了下一个if的条件”的情况

  • 相关阅读:
    Autoit 使用
    小狼毫安装五笔输入法
    MIT 6.824 MapReduce
    基于JDBC封装数据库基本CURD操作
    利用反射特性完成对象的拷贝
    基于HTTP协议和HttpURLConnection完成网上资源的爬取
    应用多线程解决文件拷贝加进度条项目
    java动态代理详解
    [转]String、StringBuffer与StringBuilder之间区别
    “内聚性”和“耦合性”
  • 原文地址:https://www.cnblogs.com/kiwibird/p/5015887.html
Copyright © 2011-2022 走看看