当写算法题遇到奇怪的输入格式要求时

66 阅读3分钟

PTA总是在输入数据这块搞些个奇奇怪怪的东西

之前是那个空白行,这次来了个这个

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

输入样例:

abcd123ab888efghij45ef67kl,ab,ef

那么呢 根据上次的经验,我们还是要巧妙地利用**&&**。

解决方法:

char s[1000], s1[20], s2[20], c;
int l = 0 , l1 = 0 , l2 = 0;
while ((c = getchar()) && c != ',')//一个一个字符地接收
		s[l++] = c;//输入字符数组s
while ((c = getchar()) && c != ',')
		s1[l1++] = c;//输入字符数组s1
while ((c = getchar()) && c != EOF)
		s2[l2++] = c;//输入字符数组s2

(或者这样子 (学长的方法)(有点子神奇))

string str;
    getline(cin, str);//先接收整个一行输入的东西
    int len = str.size();
    int pos1 = -1, pos2 = -1;
    for(int i = 0; i < len; i++) {
        if(str[i] == ',') {
            if(pos1 == -1) {//这个判断就是看遍历到的是第一个逗号还是第二个
                pos1 = i;//记录下逗号的位置为字符串分开的标志
            } else {
                pos2 = i;//同上
            }
        }
    }
    string s = str.substr(0, pos1);//巧妙地运用string.substr函数把字符串提出来
    string s1 = str.substr(pos1+1, pos2 - pos1 - 1);
    string s2 = str.substr(pos2+1, len);

这道题感觉还

是不错的,记录一下吧

7-7 h0093. 字符串最大跨距 (20 分)

有三个字符串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,字符串之间用逗号隔开。

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

输出格式:

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

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

输入样例:

abcd123ab888efghij45ef67kl,ab,ef

输出样例:

18

我还以为这道题要用kmp,发现好像不用那么麻烦

  1. //我们想要检测S1和S2是否同时在S中出现,且S1位于S2的左边,并在S中互不交叉

  2. //所以我们要检查s1在s中第一次出现的位置和s2在s中最后一次出现的位置

  3. //后者减前者为最大跨度,如果小于零说明不满足题意则要输出-1

    #include<bits/stdc++.h> using namespace std;

    int main() { string str; //先接收全部输入的东西 getline(cin,str); int len = str.size(); int pos1 = -1, pos2 = -1;//设置两个标志逗号的变量初始化为不会作为下标的数-1 for(int i = 0; i < len; i++) { if(str[i] == ',') { if(pos1 == -1)//如果pos1等于-1说明遇到的是第一个逗号 pos1=i; else //否则遇到的是第二个 pos2=i; } } int l = pos1,l1 = pos2-pos1-1,l2=len-pos2-1;//注意字符串下标是从0开始记录的哦 //cout<<l<<endl<<l1<<endl<<l2<<endl;//测试长度是否运算正确 string s=str.substr(0,l); string s1=str.substr(pos1+1,l1); string s2=str.substr(pos2+1,l2); //cout<<s<<endl<<s1<<endl<<s2<<endl;//测试字符串提取是否正确

    int ans = 0;//ans=s2最后出现的首字母前一个字符下标-s1第一次出现的最后一个字符的后一个字符下标
    int i,k=0;//k为连续匹配字符长度
    for(i = 0; i < l; i++)
    {
        if(s[i] == s1[k])
            k++;//相同就继续匹配,k++
        else
            k=0;//否则k重置为0
        if(k == l1)
        {
            ans-=i+1;//找到了第一个匹配处,最后的结果是要减去s1第一次出现的后面一个位置的下标
            break;//跳出循环
        }
    }
    int j=l2-1;
    for(i = l;i >= 0; i--)//从后往前遍历
    {
        if(s[i] == s2[j])
            j--;//相同就继续匹配,子字符串也反过来遍历匹配
        else
            j=l2-1;//否则重置为l2-1(因为字符串是从下标0开始的,所以要-1)
        if(j == 0)
        {
            ans+=i-1;//找到了s2最后出现的匹配处,它的前一个位置下标作为减数
            break;
        }
    }
    if(ans >= 0)//如果ans<0说明不满足题目要求
        cout<<ans;
    else
        cout<<"-1";
    
    return 0;
    

    }