Poetry is a form of literature that uses aesthetic and rhythmic qualities of language. There are many famous poets in the contemporary era. It is said that a few ACM-ICPC contestants can even write poetic code. Some poems has a strict rhyme scheme like "ABABA" or "ABABCAB". For example, "niconiconi" is composed of a rhyme scheme "ABABA" with A = "ni" and B = "co".
More technically, we call a poem pretty if it can be decomposed into one of the following rhyme scheme: "ABABA" or "ABABCAB". The symbolA,B and C are different continuous non-empty substrings of the poem. By the way, punctuation characters should be ignored when considering the rhyme scheme.
You are given a line of poem, please determine whether it is pretty or not.
Input
There are multiple test cases. The first line of input contains an integerT indicating the number of test cases. For each test case:
There is a line of poem S (1 <= length(S) <= 50).S will only contains alphabet characters or punctuation characters.
Output
For each test case, output "Yes" if the poem is pretty, or "No" if not.
Sample Input
3
niconiconi~
pettan,pettan,tsurupettan
wafuwafu
Sample Output
Yes
Yes
No
开始听了LJH的方法把ABABA和ABABCAB 转换成(AB()AB)A和(AB)(AB)(CAB)。就变成了:AA+A的前缀和AA+一个包含A后缀的C结果发现不行,前者还比较好弄,后者没办法把AB分开所以也就不能将A和B相等的情况否定。肯定会将一些AB相等的算作Yes
看了AC的正确代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <ctype.h>
#include <math.h>
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
using namespace std;
void judge(string str) {
string sa1 , sa2 , sa3 , sb1 , sb2 , sb3 , sc ;
for(int la = 1 ; la < (int)str.length() ; ++la) {
for(int lb = 1 ; lb < (int)str.length() ; ++lb) {
if(3*la + 2*lb == (int)str.length()) {
sa1 = str.substr(0 , la) ;
sa2 = str.substr(la+lb , la) ;
sa3 = str.substr(2*(la+lb) , la) ;
sb1 = str.substr(la , lb) ;
sb2 = str.substr(2*la+lb , lb) ;
if(sa1 == sa2 && sa2 == sa3 && sb1 == sb2 && sa1 != sb1) {
printf("Yes\n") ;
return ;
}
}
if(3*la + 3*lb < (int)str.length()) {
int lc = (int)str.length()-3*la-3*lb ;
sa1 = str.substr(0 , la) ;
sa2 = str.substr(la+lb , la) ;
sa3 = str.substr(2*la+2*lb+lc , la) ;
sb1 = str.substr(la , lb) ;
sb2 = str.substr(2*la+lb , lb) ;
sb3 = str.substr(3*la+2*lb+lc , lb) ;
sc = str.substr(2*la+2*lb , lc) ;
if(sa1 == sa2 && sa1 == sa3 && sb1 == sb2 && sb1 == sb3 && sa1 != sb1 && sa1 != sc && sb1 != sc) {
printf("Yes\n") ;
return ;
}
}
}
}
printf("No\n") ;
}
int main()
{
int t ;
scanf("%d" ,&t) ;
while(t--) {
string str ;
cin>>str ;
for(int i = 0 ; i < (int)str.length() ; ++i) {
if(isalpha(str[i]) == false) {
str.replace(i , 1 ,"") ;
--i ;
}
}
judge(str) ;
}
return 0;
}
用了STRING,但我对STRING还不是很熟,就想写一个不用STRING的,也用他们的这个思想。
但是写的过程出现了很多问题。
首先是模仿写一个str.substr(0 , la) ;开始写了一个这样的sub
char* sub(char* s,int a,int b)
{
char str[155];
int k=0;
for(int i=a;i<=b;i++)
{
str[k++]=s[i];
}
str[k]='\0';
return str;
}
但是编译器有一个警告,而且最后也没有AC我不知道原因是什么,自己试的结果都正确
警告的原因是char str[155];申请的空间会在函数结束销毁,正确的写法是
char * substr(const char * s, int n1, int n2) /*从s中提取下标为n1~n2的字符组成一个新字符串,然后返回这个新串的首地址*/
{
char * sp = (char*)malloc(sizeof(char) * (n2 - n1 + 2));
int i, j = 0;
for (i = n1; i <= n2; i++)
{
sp[j++] = s[i];
}
sp[j] = 0;
return sp;
}</span>
这样申请堆空间,最后用完之后要手动释放
sub = substr(s, 0, 5); /*提取s[0]~s[5]元素组成新子串,并保存到sub中*/
free(sub);/*释放sub所占用的空间*/
</span>
更多有关返回一个字符串的方法参考另一篇文章:http://blog.csdn.net/turkeyzhou/article/details/6104135
最后我使用了函数参数而不适用返回值来得到字串
void sub(char str[],char s[],int a,int b)
{
int k=0;
for(int i=a;i<b+a;i++)
{
str[k++]=s[i];
}
str[k]='\0';
}</span>
最后也AC了。
#include<queue>
#include<math.h>
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 1555
void sub(char str[],char s[],int a,int b)
{
int k=0;
for(int i=a;i<b+a;i++)
{
str[k++]=s[i];
}
str[k]='\0';
}
int main()
{
int tt;
scanf("%d",&tt);
while(tt--)
{
char a[N],b[N];
cin>>b;
int k=0;
for(int i=0;i<(int)strlen(b);i++)
{
if( (b[i]>='A'&&b[i]<='Z') || (b[i]>='a'&&b[i]<='z'))
a[k++]=b[i];
}
a[k]='\0';
char a1[N],a2[N],a3[N],b1[N],b2[N],b3[N],c[N];
int len=strlen(a);
int flag=0;
for(int i=1;i<=len/2;i++){
if(flag)break;
for(int j=1;j<=len/2;j++){
if(3*i+2*j==len){
sub(a1,a,0,i);
sub(b1,a,i,j);
sub(a2,a,i+j,i);
sub(b2,a,i+j+i,j);
sub(a3,a,i+j+i+j,i);
if(strcmp(a1,a2)==0&&strcmp(a2,a3)==0&&strcmp(b1,b2)==0&&strcmp(a1,b1)!=0){
flag=1;
break;
}
}
}
}
for(int i=1;i<=len/2;i++){
if(flag==2)break;
for(int j=1;j<=len/2;j++){
if(flag==2)break;
for(int k=1;k<=len/2;k++){
if(3*i+3*j+k==len){
sub(a1,a,0,i);
sub(b1,a,i,j);
sub(a2,a,i+j,i);
sub(b2,a,i+j+i,j);
sub(c,a,2*i+2*j,k);
sub(a3,a,2*i+2*j+k,i);
sub(b3,a,3*i+2*j+k,j);
if(strcmp(a1,a2)==0&&strcmp(a2,a3)==0&&strcmp(b1,b2)==0&&strcmp(b2,b3)==0&&strcmp(a1,b1)!=0&&strcmp(a1,c)!=0&&strcmp(b1,c)!=0){
flag=2;
break;
}
}
}
}
}
if(flag)puts("Yes");
else puts("No");
}
return 0;
}
不过AC之前我还犯了一个错误,再判断ABABCAB这种时,我只比较了b1和b2相同,没有比较b2和b3相同,结果抓耳挠腮了半天不知道WA的原因,还是不够仔细。
if(strcmp(a1,a2)==0&&strcmp(a2,a3)==0&&strcmp(b1,b2)==0&&strcmp(b2,b3)==0&&strcmp(a1,b1)!=0&&strcmp(a1,c)!=0&&strcmp(b1,c)!=0){
开始少了&&strcmp(b2,b3)==0这句!