• 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的条件”的情况

  • 相关阅读:
    福大软工1816 · 第五次作业
    福大软工1816
    福大软工1816 · 第三次作业
    福大软工1816 · 第二次作业
    福大软工1816 · 第一次作业
    1/10
    福大软工 · 第七次作业
    福大软工 · 第八次作业(课堂实战)- 项目UML设计(团队)
    2018软工第六次作业
    福大软工1816 · 第五次作业
  • 原文地址:https://www.cnblogs.com/kiwibird/p/5015887.html
Copyright © 2020-2023  润新知