Crusaders Quest ZOJ

来源:互联网 发布:淘宝地址转换微信 编辑:程序博客网 时间:2024/06/09 18:24

题意

给我们一个字符串 其中只有a,o,g 当三个相同字符连在一起时释放大技能
我们可以消除任意连续数量的字符 
问我们最大的释放大技能的数量是多少

分析

首先答案只能是 1 2 3
如果这个字符串中存在连续三个的我们可以直接消去 删掉
3个的情况就是三个通过删除的过程中可以形成或是已经就是三个的情况
直接删除
当我们在构造一个字符连着的三个时 我们需要删除这个字符中间的字符 那么如果我们要寻找以某字符连续三个的字符串时 我们要把中间的字符删掉 那么删除的过程中 如果删除种类数是两个 那么以此构造的解最大为1 
如果删除的过程中种类只有一个 那么还有可能是2
我们剩下的情况 为了构造三个连续相同的字符串 我们总要删除一两个不同种类的字符
因为此时不删除已经得不到三个连续相同的字符串了 
为了构造最大解 那么此时我们不妨就不断枚举要删除的字符 如果删除目标字符后能找到个三个连续的那么就说明解一定是2 因为如果删除一个字符后 能找到三个连续相同 删掉后剩下的一定仍然是连续相同 如果删除一个特定字符后找不到任何连续的 那么就说明只能构造出1个可行解 只能再删一个字符

#include <bits/stdc++.h>using namespace std;string l,tmp;int ans;int cnt(string &tmp){    int a=0,t=0;    while(tmp.length()&&t<3){//找连续的三个字符        t++;        if(tmp.find("aaa",0)!=string::npos){            tmp.erase(tmp.find("aaa",0),3);            a++;        }        else if(tmp.find("ggg",0)!=string::npos){            tmp.erase(tmp.find("ggg",0),3);            a++;        }        else if(tmp.find("ooo",0)!=string::npos){            tmp.erase(tmp.find("ooo",0),3);            a++;        }    }    return a;}int del(char c,string tmp){    int f=0;    int len = tmp.length();    for(int i=0;i<len;){        if(tmp[i]==c)tmp.erase(i,1),f++;        else i++;    }    if(f){        int p = cnt(tmp);        if(p==0)return 1;// 如果没有找到更多的连续 说明可以继续消除返回1        else return p;// 如果找到了 说明消除一个后 可以继续消除返回p    }    else return 0;}//aaggaogooint main (void) {    int n;    scanf("%d ",&n);    while(n--){        getline(cin,l);        tmp = l;        ans+=cnt(tmp);        string rep = tmp;        if(ans!=3)            ans+=max(max(del('a',rep),del('o',rep)),del('g',rep));        printf("%d\n",ans);        ans=0;    }    return 0;}
原创粉丝点击