Acwing 778. 字符串最大跨距 和777,779

Acwing 778. 字符串最大跨距

有三个字符串S,S1,S2,其中,S长度不超过300,S1和S2的长度不超过10。

现在,我们想要检测S1和S2是否同时在S中出现,且S1位于S2的左边,并在S中互不交叉(即,S1的右边界点在S2的左边界点的左侧)。

计算满足上述条件的最大跨距(即,最大间隔距离:最右边的S2的起始点与最左边的S1的终止点之间的字符数目)。

如果没有满足条件的S1,S2存在,则输出-1。

例如,S = “abcd123ab888efghij45ef67kl”, S1=”ab”, S2=”ef”,其中,S1在S中出现了2次,S2也在S中出现了2次,最大跨距为:18。

输入格式

输入共一行,包含三个字符串S,S1,S2,字符串之间用逗号隔开。

数据保证三个字符串中不含空格和逗号。

输出格式

输出一个整数,表示最大跨距。

如果没有满足条件的S1和S2存在,则输出-1.

输入样例:

abcd123ab888efghij45ef67kl,ab,ef

输出样例:

18

 

题解

 

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
    string s,s1,s2;
    char c;
    while(cin>>c,c!=',') s=s+c;
    while(cin>>c,c!=',') s1=s1+c;
    while(cin>>c) s2=s2+c;
    if(s.size()<s1.size()||s.size()<s2.size()) puts("-1");  //排除边界条件
    else
    {
        int l=0;                            //s1起点
        while(l+s1.size()<=s.size()){       //不越界
            int k=0;
            while(k<s1.size()){             //从s1第一个字符开始匹配
                if(s[l+k]!=s1[k]) break;    //如果匹配不上直接break
                k++;                        //匹配上了k++跳向下一个字符
            }
            if(k==s1.size()) break;         //如果每个字符都匹配上了就break
            l++;                            //否则进入下一个起点
        }
                                            //同理处理s2
        int r=s.size()-s2.size();           //s2起点 注意右向左遍历
        while(r>=0)                         //倒着遍历
        {
            int k=0;                        
            while(k<s2.size()){
                if(s[r+k]!=s2[k]) break;    //如果匹配不上直接break
                k++;                        //跳向下一个字符
            }
            if(k==s2.size()) break;         //全部成功 break
            r--;                            //不成功 继续r--左移至下一个起点
        }
        
        l+=s1.size();                       //s1的起点左移s1的长度再即s1的最右头
        
        if(l>=r) puts("-1");                //l>=r即s1s2交叉
        else{
            cout<<r-l<<endl;                
        }
    }
    return 0;
}

 

 

 

777. 字符串乘方

 

 

给定两个字符串a和b,我们定义a*b为他们的连接。

例如,如果a=”abc” 而b=”def”, 则a*b=”abcdef”。

如果我们将连接考虑成乘法,一个非负整数的乘方将用一种通常的方式定义:a0a0=””(空字符串),a(n+1)a(n+1)=a∗(an)a∗(an)。

输入格式

输入包含多组测试样例,每组测试样例占一行。

每组样例包含一个字符串s,s的长度不超过100。

最后的测试样例后面将是一个点号作为一行。

输出格式

对于每一个s,你需要输出最大的n,使得存在一个字符串a,让s=ans=an。

输入样例:

abcd
aaaa
ababab
.

输出样例:

1
4
3

 

 

题解

#include<iostream>
#include<string>
using namespace std;
int main()
{
    string str;
    while(cin>>str,str!="."){                       //读串
        int len=str.size();
        for(int n=str.size();n>=0;n--){             //倒着枚举最长子串
            if(len%n==0){                           //n为a的次数,一定是a的约数,排除别的情况
                int m=len/n;
                string s=str.substr(0,m);           //得到长m的字串
                string r;
                for(int i=0;i<n;i++){               //子串重复n次拼起来
                    r=r+s;
                }
                if(r==str){                         //比较若相等输出次数n
                    cout<<n<<endl;                  //由于倒着枚举第一个break的即为最大值
                    break;
                }
            }
        }
    }
    return 0;
}

 

779. 最长公共字符串后缀

 

给出若干个字符串,输出这些字符串的最长公共后缀。

输入格式

由若干组输入组成。

每组输入的第一行是一个整数N。

N为0时表示输入结束,否则后面会继续有N行输入,每行是一个字符串(字符串内不含空白符)。

每个字符串的长度不超过200。

输出格式

共一行,为N个字符串的最长公共后缀(可能为空)。

数据范围

1≤N≤2001≤N≤200

输入样例:

3
baba
aba
cba
2
aa
cc
2
aa
a
0

输出样例:

ba

a

 

题解

 

 

#include<iostream>
#include<string>
using namespace std;
const int N = 200;
int n;
string str[N];
int main()  
{
    while(cin>>n,n!=0){
        int len=1000;               //读str[]的最小长度用
        for(int i=0;i<n;i++){
            cin>>str[i];            //初始化
            if(len>str[i].size()) len=str[i].size();  //str最小长度为str后缀的最大长度
        }
        while(len>0){               //枚举后缀 从len开始 l--
            bool success=true;      
            for(int i=1;i<n;i++){   //枚举所有字符串的后len个字符是不是一样,从第二个字符串开始
                bool is_same=true;
                for(int j=1;j<=len;j++){
                    if(str[0][str[0].size()-j]!=str[i][str[i].size()-j]){
                    //str[0][str[0].size()-j]为str[0]的最后一个字符
                    //去匹配str[i]的最后一个字符,若匹配则不进入if,j++判断倒数第二个字符
                    //若不匹配则进入if
                        is_same=false;
                        break;
                    }
                }
                if(!is_same){       //若is_same!=true 即匹配失败,后len个字符不一样
                    success=false;  //然后直接break令len--去减少后缀的长度再继续匹配
                    break;
                }
            }
            if(success) break;
            len--;
        }
        cout<<str[0].substr(str[0].size()-len)<<endl;   //输出str[0]的后len个字符
        //cout<<str[0].substr(str[0].size())<<endl;
        //cout<<len<<endl;
        //cout<<str[0]<<endl;
    }
    return 0;
}

 

substr有2种用法:
        假设:string s = "0123456789";
        string sub1 =s.substr(5);//只有一个数字5表示从下标为5开始一直到结尾:sub1 = "56789"
        string sub2 =s.substr(5, 3);//从下标为5开始截取长度为3位:sub2 = "567"

 

 

 

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页