红和绿

 

 

思路:用递归,考虑所有可能情况。  当前‘G'后'R'时,要么将R前面所有的连续的G变为R,要么将R变为G,分别计算其更改后的字符串和更改次数,进入下次递归。

注意点:要考虑全染为一色的情况,和不全染为一色(用递归解决,注意此时开头必为红色,结尾必为绿色,需要判断)

#include<iostream>
#include<string>
using namespace std;
int minn;
int len;
void dfs(int pre,int back,int sum,string str){
    if(back >= len){
        if(minn==0){
            minn = sum;
            return;
        }else{
            if(minn>sum){
                minn = sum;
            }
            return;
        }
    }
    if(str[pre]=='G' && str[back]=='R'){    
        //要么将R前面所有的连续的G变为R,要么将R变为G
        string temp = str;
        int t=sum;
        for(int i=pre;i>=0;i--){//R前面所有的连续的G变为R
            if(temp[i] == 'G'){
                temp[i] = 'R';
                t++;
            }else{
                break;
            }
        }
        dfs(pre+2,back+2,t,temp);
        temp = str;
        temp[back] = 'G';
        dfs(pre+1,back+1,sum+1,temp);            //R变为G
    }else{
        pre++;
        back++;
        dfs(pre,back,sum,str);
    }
}
int main()
{
    string s;
    cin>>s;
    len = s.length();
    int sum = 0;
    int t1=0,t2=0;
    for(int i=0;i<len;i++){
        if(s[i]=='G'){
            t1++;
        }else{
            t2++;
        }
    }
    minn = t1<t2?t1:t2;
    
    if(s[0]=='G'){
        s[0] = 'R';
        sum++;
    }
    if(s[len-1]=='R'){
        s[len-1] = 'G';
        sum++;
    }
    dfs(0,1,sum,s);
    cout<<minn;
    return 0;
}

 

 

其他题解:(处理所有可能情况)
对长度为n的字符串,对其每个位置对进行处理,把该位置左侧全染为R,再把该位置右侧全染为G,计算需要染的次数,获取最小次数即可

#include <stdio.h>
#include <string.h>
#define N 50
int main()
{
    char ch[N];
    scanf("%s",ch);
    int n,i,j,count=0;
    n=strlen(ch);
    int min=n;
    for(i=0;i<n;i++)
    {
        count=0;
        for(j=0;j<i;j++)
            if(ch[j]=='G')
                count++;
        for(j=i;j<n;j++)
            if(ch[j]=='R')
                count++;
        if(count<min)
            min=count;
    }
    printf("%d\n",min);
    return 0;
}

 

posted @ 2019-04-29 12:00  萌新上路  阅读(160)  评论(0编辑  收藏  举报