• 【CF676C】Vasya and String(二分查找,线性扫描尺取法)


    题意:

    给出一个长度为n的字符串,只有字符'a'和'b'。最多能改变k个字符,即把'a'变成'b'或把'b'变成'a'。

    问改变后的最长连续相同字符的字串长度为多少。

    首先是二分查找,好想也好写

     1 var s:array[0..100000]of longint;
     2     ch:ansistring;
     3     n,k,i,l,r,mid,last,ans:longint;
     4 
     5 function max(x,y:longint):longint;
     6 begin
     7  if x>y then exit(x);
     8  exit(y);
     9 end;
    10 
    11 begin
    12  //assign(input,'1.in'); reset(input);
    13  //assign(output,'1.out'); rewrite(output);
    14  readln(n,k);
    15  readln(ch);
    16  for i:=1 to n do
    17  begin
    18   s[i]:=s[i-1];
    19   if ch[i]='b' then inc(s[i]);
    20  end;
    21  ans:=0;
    22  for i:=1 to n do
    23   begin
    24   l:=i; r:=n; last:=i;
    25   while l<=r do
    26   begin
    27    mid:=(l+r)>>1;
    28    if s[mid]-s[i-1]<=k then begin last:=mid; l:=mid+1; end
    29     else r:=mid-1;
    30   end;
    31   ans:=max(ans,last-i+1);
    32  end;
    33  fillchar(s,sizeof(s),0);
    34  for i:=1 to n do
    35  begin
    36   s[i]:=s[i-1];
    37   if ch[i]='a' then inc(s[i]);
    38  end;
    39  for i:=1 to n do
    40   begin
    41   l:=i; r:=n; last:=i;
    42   while l<=r do
    43   begin
    44    mid:=(l+r)>>1;
    45    if s[mid]-s[i-1]<=k then begin last:=mid; l:=mid+1; end
    46     else r:=mid-1;
    47   end;
    48   ans:=max(ans,last-i+1);
    49  end;
    50  writeln(ans);
    51  //close(input);
    52  //close(output);
    53 end.
    View Code

     然后是线性扫描,ACM叫做尺取法,机房大神叫伸头缩尾法

    l循环后还要+1是因为要到下一段连续区间的开头,而当前连续间的字母和下一段一定不同(显然要找最长的连续相同序列),先默认将开头字母改好

     1 var ch:ansistring;
     2     n,k,ans,r,l,i,t:longint;
     3 
     4 function max(x,y:longint):longint;
     5 begin
     6  if x>y then exit(x);
     7  exit(y);
     8 end;
     9 
    10 begin
    11  //assign(input,'1.in'); reset(input);
    12  //assign(output,'1.out'); rewrite(output);
    13  readln(n,k);
    14  readln(ch);
    15  l:=1; r:=1; t:=0;
    16  for i:=1 to n do
    17  begin
    18   if ch[i]='b' then
    19   begin
    20    if t<k then begin inc(t); inc(r); end
    21     else
    22     begin
    23      while (l<=n)and(ch[l]='a') do inc(l);
    24      inc(l);
    25      inc(r);
    26     end;
    27   end
    28    else inc(r);
    29   ans:=max(ans,r-l);
    30  end;
    31  l:=1; r:=1; t:=0;
    32  for i:=1 to n do
    33  begin
    34   if ch[i]='a' then
    35   begin
    36    if t<k then begin inc(t); inc(r); end
    37     else
    38     begin
    39      while (l<=n)and(ch[l]='b') do inc(l);
    40      inc(l);
    41      inc(r);
    42     end;
    43   end
    44    else inc(r);
    45   ans:=max(ans,r-l);
    46  end;
    47  writeln(ans);
    48  //close(input);
    49  //close(output);
    50 end.
    View Code
  • 相关阅读:
    阻止事件冒泡
    移动端开发
    angular6 管道多参数传输 Pipe
    在div上添加小三角
    angular6 使用@Input() @Output()
    angular6 想要获取页面某些事件 如 点击 window宽高等等
    如何将项目添加到git上
    使用vue-cli 搭建element-admin后台
    bootstrap4 常用样式类名 (供自己参考)
    键盘按下 keyCode 的值
  • 原文地址:https://www.cnblogs.com/myx12345/p/5557395.html
Copyright © 2020-2023  润新知