Automatic Poetry
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 2202 | Accepted: 1119 |
Description
Background
"Oh God", Lara Croft exclaims, "it's one of these dumb riddles again!"
In Tomb Raider XIV, Lara is, as ever, gunning her way through ancient Egyptian pyramids, prehistoric caves and medival hallways. Now she is standing in front of some important Germanic looking doorway and has to solve a linguistic riddle to pass. As usual, the riddle is not very intellectually challenging.
This time, the riddle involves poems containing a "Schuttelreim". An example of a Schuttelreim is the following short poem:
The Problem
A Schuttelreim seems to be a typical German invention. The funny thing about this strange type of poetry is that if somebody gives you the first line and the beginning of the second one, you can complete the poem yourself. Well, even a computer can do that, and your task is to write a program which completes them automatically. This will help Lara concentrate on the "action" part of Tomb Raider and not on the "intellectual" part.
"Oh God", Lara Croft exclaims, "it's one of these dumb riddles again!"
In Tomb Raider XIV, Lara is, as ever, gunning her way through ancient Egyptian pyramids, prehistoric caves and medival hallways. Now she is standing in front of some important Germanic looking doorway and has to solve a linguistic riddle to pass. As usual, the riddle is not very intellectually challenging.
This time, the riddle involves poems containing a "Schuttelreim". An example of a Schuttelreim is the following short poem:
Ein Kind halt seinen Schnabel nur,
wenn es hangt an der Nabelschnur.
The Problem
A Schuttelreim seems to be a typical German invention. The funny thing about this strange type of poetry is that if somebody gives you the first line and the beginning of the second one, you can complete the poem yourself. Well, even a computer can do that, and your task is to write a program which completes them automatically. This will help Lara concentrate on the "action" part of Tomb Raider and not on the "intellectual" part.
Input
The input will begin with a line containing a single number n. After this line follow n pairs of lines containing Schuttelreims. The first line of each pair will be of the form
s1<s2>s3<s4>s5
where the si are possibly empty strings of lowercase characters or blanks. The second line will be a string of lowercase characters or blanks ending with three dots "...". Lines will we at most 100 characters long.
where the si are possibly empty strings of lowercase characters or blanks. The second line will be a string of lowercase characters or blanks ending with three dots "...". Lines will we at most 100 characters long.
Output
For each pair of Schuttelreim lines l1 and l2 you are to output two lines c1 and c2 in the following way: c1 is the same as l1 only that the bracket marks "<" and ">" are removed. Line c2 is the same as l2, except that instead of the three dots the string
s4s3s2s5
should appear.
should appear.
Sample Input
3 ein kind haelt seinen <schn>abel <n>ur wenn es haengt an der ... weil wir zu spaet zur <>oma <k>amen verpassten wir das ... <d>u <b>ist ...
Sample Output
ein kind haelt seinen schnabel nur wenn es haengt an der nabel schnur weil wir zu spaet zur oma kamen verpassten wir das koma amen du bist bu dist
每组的第一个 删去括号,输出;
第二个去掉省略号,后面接第一个串的括号内的字符全部交换的子串,如输出
本来是向用练练string函数的,结果WA,如果括号内的字符为空,则string不好返回
WA:
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int main()
{
int n;
cin>>n;
string s1,s2;
getchar();
while(n--){
getline(cin,s1);
string cpys1 = s1;
int pot1 = s1.find("<",0);
int pot2 = s1.find(">",0);
int pot3 = s1.find("<",pot2+1);
int pot4 = s1.find(">",pot3+1);
cpys1.erase(pot1,1);
cpys1.erase(pot2-1,1);
cpys1.erase(pot3-2,1);
cpys1.erase(pot4-3,1);
cout<<cpys1<<endl;
getline(cin,s2);
int pot5 = s2.find(".",0);
s2.erase(pot5,3);
// string cpys2=s2;
string s3 = s1.substr(pot1+1,pot2-pot1-1);
string s4 = s1.substr(pot3+1,pot4-pot3-1);
string s5 = s1.substr(pot2+1,pot3-pot2-2);
string s6 = s1.substr(pot4+1,s1.length()-pot3+1);
cout<<s3<<endl<<s4<<endl<<s5<<endl<<s6<<endl;
s4+=s5;
s3+=s6;
cout<<s2<<s4<<" "<<s3<<endl;
}
}
C++ string类AC:
#include <iostream>
#include <cstdio>
#include <string>
using namespace std;
int main()
{
int tc, len1, len2, i, j, pos1, pos2, pos3, pos4;
string input1, input2, s1, s2, s3, s4, s5, s6;
bool flag1, flag2;
cin >> tc;
cin.get();//放在这里才对
while (tc--){
//cin.get();//之前放在这个位置,无限WA,因为每一次都取一个,所以就造成了输入的出错!
getline(cin, input1);
getline(cin, input2);
s1.clear();
s2.clear();
s3.clear();
s4.clear();
s5.clear();
s6.clear();
flag1 = true;
flag2 = true;
len1 = input1.length();
len2 = input2.length();
for (i = 0; i < len1; i++){
if (input1[i] == '<' && flag1){
flag1 = false;
pos1 = i;
}
else if (input1[i] == '<' && !flag1){
pos3 = i;
}
else if (input1[i] == '>' && flag2){
flag2 = false;
pos2 = i;
}
else if (input1[i] == '>' && !flag2){
pos4 = i;
}
}
for (i = 0; i < pos1; i++){
s5.push_back(input1[i]);
}
for (i = pos1+1; i < pos2; i++){
s1.push_back(input1[i]);
}
for (i = pos2+1; i < pos3; i++){
s2.push_back(input1[i]);
}
for (i = pos3+1; i < pos4; i++){
s3.push_back(input1[i]);
}
for (i = pos4+1; i < len1; i++){
s4.push_back(input1[i]);
}
for (i = 0; i < len2 && input2[i] != '.'; i++){
s6.push_back(input2[i]);
}
cout << s5 << s1 << s2 << s3 << s4 << endl;
cout << s6 << s3 << s2 << s1 << s4 << endl;
}
}
数组做AC:
#include <stdio.h>
#include <string.h>
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
char s1[101],s2[101],s3[101],s4[101],line[105],*ch;
int i,j,k,len,s1n,s2n,s3n,s4n,n;
scanf("%d",&n); gets(line);
while(n--){
gets(line);
len=strlen(line);
k=j=0;
s1n=s2n=s3n=s4n=0;
for(i=0;i<len;i++){
if(line[i]=='<' || line[i]=='>'){k++;continue;}
if(k==1) s1[s1n++]=line[i];
if(k==2) s2[s2n++]=line[i];
if(k==3) s3[s3n++]=line[i];
if(k==4) s4[s4n++]=line[i];
printf("%c",line[i]);
}
printf("\n");
gets(line);
len=strlen(line);
for(i=0;i<len;i++) if(line[i]=='.' && line[i+1]=='.' && line[i+2]=='.') break;
for(j=0;j<i;j++) printf("%c",line[j]);
for(j=0;j<s3n;j++) printf("%c",s3[j]);
for(j=0;j<s2n;j++) printf("%c",s2[j]);
for(j=0;j<s1n;j++) printf("%c",s1[j]);
for(j=0;j<s4n;j++) printf("%c",s4[j]);
// for(i+=3;i<len;i++) printf("%c",line[i]);打印出省略号后面的 有必要?
printf("\n");
}
return 1;
}
网上不小心看到了建哥的代码:
#include <stdio.h>
#include <string.h>
char str[2][110];
int main()
{
int n,mark[4];
char x;
scanf("%d%c",&n,&x);
while(n--){
gets(str[0]);
gets(str[1]);
int len0=strlen(str[0]);
for(int i=0,j=0;i<len0;i++){
if(str[0][i]=='<'||str[0][i]=='>') { //mark用来记录下<>的位置。
mark[j]=i;
j++;
}else{
printf("%c",str[0][i]); //如果没有括号的,就直接输出就可以。
}
}
printf("\n");
for(int i=0;i<strlen(str[1])-3;i++) //调换位置。
printf("%c",str[1][i]);
for(int i=mark[2]+1;i<mark[3];i++)
printf("%c",str[0][i]);
for(int i=mark[1]+1;i<mark[2];i++)
printf("%c",str[0][i]);
for(int i=mark[0]+1;i<mark[1];i++)
printf("%c",str[0][i]);
for(int i=mark[3]+1;i<len0;i++)
printf("%c",str[0][i]);
printf("\n");
}
return 0;
}
水了这么多字符串的题,明白了一个道理,用C++string类处理的话一般都是整体处理,在整体里面处理(替换,插入,取字串等),输出也是整体输出,或者是取整体的部分整体一个个输出,而C语言+数组则是对一个个字符判断+处理,输出也是一个个控制输出。
不同语言对不同题的优势不同,看好题意,理解,然后选择,不行就换一种方法。