Journey to Un'Goro 題解(思維+剪枝搜索)


題目鏈接

題目大意

要你一構造一個長度為\(n\)的只包含\(b,r\)字符的串,使得子串中\(r\)的數量為奇數的最多

題目思路

問的qls,確實有點秒

把字符r設為1,b設為0,那么子串中r的數量就是前綴和之差,即前綴和差為奇數

那么n+1個前綴和里,奇數和偶數的個數應該盡可能相近,即前綴的奇數偶數各分一半

注意是n+1個前綴,然后爆搜即可

代碼

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
//typedef pair<int,int> pii;
#define fi first
#define se second
#define debug printf("aaaaaaaaaaa\n");
const int maxn=6e5+5,inf=0x3f3f3f3f,mod=998244353;
const ll INF=0x3f3f3f3f3f3f3f3f;
ll n;
char s[maxn];
int cnt=0;
void dfs(int now,int cnt1,int cnt2,int flag){
    // now代表第幾位,cnt1代表有幾個奇數,cnt2代表有幾個偶數,flag=0,現在為偶數 flag=1現在為奇數
    if(cnt==100) return ;
    if(n%2){ //n為奇數
        if(cnt1+(n-cnt1-cnt2)<n/2||cnt2+(n-cnt1-cnt2)<n/2||cnt1>n/2+1||cnt2>n/2+1) return ;
    }else{
        if(cnt1+(n-cnt1-cnt2)<n/2||cnt2+(n-cnt1-cnt2)<n/2||cnt1>n/2||cnt2>n/2) return ;
    }
    if(now==n){
        cnt++;
        for(int i=1;i<=n-1;i++){
            cout<<s[i];
        }
        cout<<'\n';
        return ;
    }
    s[now]='b';
    if(flag){
        dfs(now+1,cnt1+1,cnt2,flag);
    }else{
        dfs(now+1,cnt1,cnt2+1,flag);
    }
    s[now]='r';
    if(flag){
        dfs(now+1,cnt1,cnt2+1,flag^1);
    }else{
        dfs(now+1,cnt1+1,cnt2,flag^1);
    }
}
int main(){
    cin>>n;
    n++;
    cout<<(n/2)*(n-n/2)<<'\n';
    dfs(1,0,1,0);
    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM