2 条题解

  • 0
    @ 2026-9-28 20:02:31

    贪心,枚举,差分

    因为同一个点翻转两次就与没有翻转的效果相同了,因此我们有一个贪心策略为:

    从左到右对于出现的每一个B翻转一次从当前点开始的区间,就能保证是最优解。

    样例的模拟:

    如果当前翻转的区间长度为3

    粗体表示当前下标

    B B F B F B B

    (B B F) B F B B

    F F B B F B B

    F F B B F B B

    F F B B F B B

    F F (B B F) B B

    F F F F B B B

    F F F F B B B

    F F F F B B B

    F F F F (B B B)

    F F F F F F F

    F F F F F F F

    F F F F F F F

    但是我们会发现这样是n^2的,再枚举长度,就变为了n^3.因此,需要对区间翻转差分一下,总时间复杂度就是n^2的了

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn = 10009;
    int n;
    bool A[maxn],B[maxn];
    int main(){
    	scanf("%d",&n);
    	char ch;
    	for(int i=1;i<=n;++i){
    		cin>>ch;A[i]=ch=='B'?0:1;
    	}
    	int mincnt=0x7fffffff,anslen;
    	for(int len=1;len<=n;++len){
    		memset(B,0,sizeof B);
    		bool b=0,flag=1;int cnt=0;//flag记录当前长度是否有解
    		for(int i=1;i<=n;++i){//因为区间翻转只有状态0和1,所以用^代替+和-
    			b^=B[i];//数组B为记录差分的数组
    			if(!(A[i]^b)){//若当前位置为0
    				if(i+len-1>n){flag=0;break;}//唯一的失败条件:一次翻转的长度大于剩余的长度
    				b^=1,B[i+len]^=1;
    				++cnt;
    			}
    		}
    		if(flag){if(cnt<mincnt)mincnt=cnt,anslen=len;}
    	}printf("%d %d\n",anslen, mincnt);
    } 
    
    • 0
      @ 2025-10-8 17:01:50

      by hansang:

      #include<bits/stdc++.h>
      using namespace std;
      const int N=5010;
      int a[N], b[N];
      int main(){
          int n; scanf("%d", &n);
          for(int i=1; i<=n; i++){
              char s[5]; scanf("%s", s);
              if(s[0]=='B') a[i]=0;
              else a[i]=1;
          }
          int ans=1e9, res=1e9;
          for(int k=1; k<=n; k++){
              memset(b, 0, sizeof(b));
              bool flag=1;int m=0, sum=0;
              for(int i=1; i<=n; i++){
                  sum^=b[i];
                  if(!(a[i]^sum)){
                      if(i+k-1>n) {flag=0;break;}
                      sum^=1; b[i+k]^=1;
                      m++;
                  }
              }
              if(flag && m<=res) res=m, ans=k;
          }
      	printf("%d %d\n", ans, res);
      	return 0;
      }
      
      • 1

      信息

      ID
      2632
      时间
      1000ms
      内存
      128MiB
      难度
      9
      标签
      递交数
      9
      已通过
      4
      上传者