小白书练习题5.5.3 字符串类、
UVA 401 Palindromes
题意:判断是一串是否是回文串以及是否是镜像串、回文串都知道是什么意思,镜像串呢就是按题目所给的镜像进行转变,然后这个镜像串从后往前读和原串从前往后读是一样的、
思路:按题目要求来模拟、
PS:题目特别之处字母O和数字0是等价的、
1 #include<cmath> 2 #include<cstring> 3 #include<cstdio> 4 char s[50]={"A 3 HIL JM O 2TUVWXY51SE Z 8 "}; 5 char x[105]; 6 char y[105]; 7 int main() 8 { 9 while(scanf("%s",x)!=EOF){ 10 int len=strlen(x); 11 for(int i=0;i<len;++i) //处理、 12 if(x[i]=='0') x[i]='O'; 13 int a=1; 14 int b=1; 15 for(int i=0;i<len/2;++i) 16 if(x[i]!=x[len-i-1]) a=0; //是否回文、 17 int k=0; 18 for(int i=strlen(x)-1;i>=0;--i) //从最后往前进行镜像转变、 19 if(x[i]>='1'&&x[i]<='9') y[k++]=s[x[i]-'1'+26]; 20 else y[k++]=s[x[i]-'A']; 21 y[k]='\0'; 22 if(strcmp(x,y)!=0) b=0; //是否镜像、 23 printf("%s\n%s\n",x,y); 24 if(!a&&!b) printf(" -- is not a palindrome.\n"); 25 else if(a&&!b) printf(" -- is a regular palindrome.\n"); 26 else if(!a&&b) printf(" -- is a mirrored string.\n"); 27 else printf(" -- is a mirrored palindrome.\n"); 28 printf("\n"); //格式控制、 一定要注意 29 } 30 return 0; 31 }
UVA 10010 Where's Waldorf?
题意:给你一个m*n的字母矩阵、然后给你k个单词、要你从字母矩阵中找到这个单词、 找单词是有规则的、 可以找8个方向、但是方向一旦选定就只能往这个方向找
思路:也是直接模拟、
(我开始不知道是horizontally的意思.... 水平 也就是直线寻找,我直接dfs搜索了,哎贡献N次WA)
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 #include<ctype.h> 5 const int qq=60; 6 char map[qq][qq]; 7 char s[qq*qq]; 8 int m,n; 9 int flag,tx,ty,len; 10 int dx[]={-1,1,0,0,-1,-1,1,1}; //八个方向、 11 int dy[]={0,0,-1,1,1,-1,1,-1}; 12 int count; 13 int dfs(int x,int y,int cnt) 14 { 15 int i,j,k; 16 for(int l=0;l<8;++l){ 17 i=x;j=y;k=cnt; 18 while(map[i+dx[l]][j+dy[l]]==s[k]&&k<len){ 19 i+=dx[l]; 20 j+=dy[l]; 21 k++; 22 } 23 if(k>=len){ //题目要如果有多个、输出第一个单词最上也左边的那一个、 24 tx=x+1; //因为我是按从上到下从左到右开始找的、 25 ty=y+1; //所以找到的第一个也就是题目要求的那一个了、 26 return 1; 27 } 28 } 29 return 0; 30 } 31 void solve() 32 { 33 int i,j; 34 flag=0; 35 for(i=0;i<m;++i) 36 for(j=0;j<n;++j) 37 if(map[i][j]==s[0]){ 38 if(dfs(i,j,1)==1) 39 return; 40 } 41 } 42 int main() 43 { 44 int t;scanf("%d",&t); 45 getchar(); 46 while(t--){ 47 scanf("%d %d",&m,&n); 48 for(int i=0;i<m;++i){ 49 scanf("%s",map[i]); 50 for(int j=0;j<n;++j) 51 if(map[i][j]>='A'&&map[i][j]<='Z') 52 map[i][j]=tolower(map[i][j]); 53 } 54 int k;scanf("%d",&k); 55 while(k--){ 56 scanf("%s",s); 57 len=strlen(s); 58 for(int i=0;i<len;++i) 59 if(s[i]>='A'&&s[i]<='Z') 60 s[i]=tolower(s[i]); 61 solve(); 62 printf("%d %d\n",tx,ty); 63 } 64 if(t!=0) printf("\n"); 65 } 66 return 0; 67 }
UVA 10361 Automatic Poetry
题意:给你一个串s1<s2>s3<s4>s5,然后给你一个带...符号的串,要你输出两行,第一行输出去掉<>两种括号的s1s2s3s4s5,第二行要你输出将那个带...号的字符串用s4s3s2s5替代那...符号
思路:分别将s2,s3,s4,s5这四个字符串取出来、然后根据题目意思输出、
1 #include<cstring> 2 #include<cstdio> 3 #include<cmath> 4 int main() 5 { 6 int n;scanf("%d",&n); 7 getchar(); 8 while(n--){ 9 char x[105],y[105]; 10 gets(x); 11 gets(y); 12 int lenx=strlen(x); 13 int leny=strlen(y); 14 for(int i=0;i<lenx;++i) 15 if(x[i]!='<'&&x[i]!='>') printf("%c",x[i]); 16 printf("\n"); 17 for(int i=0;i<leny&&y[i]!='.';++i) 18 printf("%c",y[i]); 19 char a[100],b[100],c[100],d[100]; 20 int id=strstr(x,"<")-x; //这是从x串中找到"<"字符串出现第一个位置的函数、换返回第一次出现的位置 21 int k=0; 22 int i; //下面是分别取出四个字符串、 23 for(i=id+1;i<lenx && x[i]!='>';++i) 24 a[k++]=x[i]; 25 a[k]='\0'; 26 k=0; 27 for(i=i+1;i<lenx && x[i]!='<';++i) 28 b[k++]=x[i]; 29 b[k]='\0'; 30 k=0; 31 for(i=i+1;i<lenx && x[i]!='>';++i) 32 c[k++]=x[i]; 33 c[k]='\0'; 34 k=0; 35 for(i=i+1;i<lenx;++i) 36 d[k++]=x[i]; 37 d[k]='\0'; 38 printf("%s%s%s%s\n",c,b,a,d); 39 } 40 return 0; 41 }
UVA 537 Artificial Intelligence?
题意:给你 U I P三者中任意两者、要你求剩下的一个
思路:这题简单就是要注意的地方多、第一是所得到的值可能带有小数、另外得到的值后面还可能跟着量词单位、
1 //注意有一个数量积之间的换算 m是0.001、k是1000、M是1000000 2 #include<cmath> 3 #include<algorithm> 4 #include<cstring> 5 #include<iostream> 6 #include<cstdio> //没声明这个 DEV居然允许编译scanf和printf 7 #include<string> 8 using namespace std; //一开始居然没注意到小数点、眼瞎 9 int main() 10 { 11 int t;scanf("%d",&t); 12 getchar(); 13 int k=1; 14 char str[1005]; 15 while(t--){ 16 gets(str); 17 // puts(str); 18 printf("Problem #%d\n",k++); 19 double l,v,p; 20 int len=strlen(str); 21 l=v=p=0; 22 for(int j,i=0;i<len;++i){ 23 if(str[i]=='='){ //题目中保证了只会出现两个等于号、 24 if(str[i-1]=='U'){ //这读题一定要仔细阿、 25 int dig=0; 26 int flag=1; 27 for(j=i+1;j<len;++j) 28 if((str[j]>='0'&&str[j]<='9')||str[j]=='.'){ 29 if(str[j]=='.'){ //我这里采用忽略小数点、但是从碰到小数点开始计数、 30 flag=0; //最后有多少位小数、那么就除以10的几次方、 31 continue; 32 } 33 if(!flag) ++dig; 34 v=v*10+str[j]-'0'; 35 } 36 else break; 37 if(str[j]=='m') v=v*0.001; 38 if(str[j]=='k') v=v*1000; 39 if(str[j]=='M') v=v*1000000; 40 if(dig>=1) v=v/pow(10,dig); 41 //printf("%lf\n",v); 42 } 43 else if(str[i-1]=='P'){ 44 int dig=0; 45 int flag=1; 46 for(j=i+1;j<len;++j) 47 if((str[j]>='0'&&str[j]<='9')||str[j]=='.'){ 48 if(str[j]=='.'){ 49 flag=0; 50 continue; 51 } 52 if(!flag) ++dig; 53 p=p*10+str[j]-'0'; 54 } 55 else break; 56 if(str[j]=='m') p=p*0.001; 57 if(str[j]=='k') p=p*1000; 58 if(str[j]=='M') p=p*1000000; 59 if(dig>=1) p=p/pow(10,dig); 60 } 61 else if(str[i-1]=='I'){ 62 int dig=0; 63 int flag=1; 64 for(j=i+1;j<len;++j) 65 if((str[j]>='0'&&str[j]<='9')||str[j]=='.'){ 66 if(str[j]=='.'){ 67 flag=0; 68 continue; 69 } 70 if(!flag) ++dig; 71 l=l*10+str[j]-'0'; 72 } 73 else break; 74 if(str[j]=='m') l=l*0.001; //还有这个单位、我一直以为是一百万 英语瞎、 75 if(str[j]=='k') l=l*1000; 76 if(str[j]=='M') l=l*1000000; 77 if(dig>=1) l=l/pow(10,dig); //我开始用的居然是dig*10 真心傻逼了、 78 } 79 } 80 } 81 // printf("%lf %lf %lf\n",p,l,v); 82 if(l==0) printf("I=%.2lfA\n\n",p/v); 83 else if(v==0) printf("U=%.2lfV\n\n",p/l); 84 else printf("P=%.2lfW\n\n",v*l); 85 } 86 return 0; 87 }
UVA 409 Excuses, Excuses!
题意:给你n个单词、然后给你m句话、问你m句话中出现单词最多的话、如果有多个输出多个、输出顺序任意,同一个单词在一句话中出现a次的话 就是a次、
思路:没啥想法、直接把句子中单词一个一个抽出来匹配、
1 #include<cmath> 2 #include<cstring> 3 #include<cstdio> 4 #include<ctype.h> 5 char map[30][30]; 6 char s[30][100]; 7 int num[30]; 8 int n,m; 9 int main() 10 { 11 int t=1; 12 while(scanf("%d %d",&n,&m)!=EOF){ 13 int maxn=-1; 14 memset(num,0,sizeof(num)); 15 for(int i=0;i<n;++i) 16 scanf("%s",map[i]); 17 getchar(); //用gets要尤为注意回车、 这里要将这个回车吸取掉、 18 for(int i=0;i<m;++i){ //不然会被gets读取掉、 19 gets(s[i]); 20 int flag=0; 21 int len; 22 len=strlen(s[i]); 23 char c[75]; 24 int k=0; 25 for(int j=0;j<len;++j) 26 if(s[i][j]>='A'&&s[i][j]<='z'){ //题目认为大写字母和小写字母相同、 27 c[k++]=tolower(s[i][j]); 28 flag=1; //标志有单词出现、 29 } 30 else{ 31 if(flag==1){ 32 c[k]='\0'; 33 for(int l=0;l<n;++l) 34 if(strcmp(map[l],c)==0){ 35 num[i]++; 36 break; 37 } 38 } 39 flag=0; 40 k=0; 41 } 42 if(num[i]>maxn) maxn=num[i]; 43 } 44 printf("Excuse Set #%d\n",t++); 45 for(int i=0;i<m;++i) 46 if(num[i]==maxn) printf("%s\n",s[i]); 47 printf("\n"); 48 } 49 return 0; 50 }
UVA 10878 Decode the tape
题意:这是一道脑洞题、说实在的我没想出来
1 #include<cmath> 2 #include<cstring> 3 #include<cstdio> 4 int num[]={0,0,64,32,16,8,0,4,2,1,0}; 5 int main() //真心没想到这题的思路、 6 { 7 char s[105]; 8 gets(s); //先把第一行的_______给读取掉 9 while(gets(s)&&s[0]!='_'){ 10 int ans=0; 11 for(int i=strlen(s)-1;i>=0;--i) 12 if(s[i]=='o') ans+=num[i]; 13 printf("%c",ans); 14 } 15 return 0; 16 }
UVA 10815 Andy's First Dictionary
题意:给你一篇文章、让你找出其中所有互不相同的单词(输出小写)
思路:一个一个单词全部化为小写存起来、然后快排一次,比较输出、
1 #include<cmath> 2 #include<cstring> 3 #include<cstdio> 4 #include<ctype.h> 5 const int qq=1e6; 6 char s[qq][210]; 7 int quicksort(int l,int r) //这里是手写快排、 8 { 9 int i,j; 10 char x[210]; 11 strcpy(x,s[l]); 12 i=l;j=r; 13 while(i<j){ 14 while(i<j && strcmp(s[j],x)>=0) --j; 15 strcpy(s[i],s[j]); 16 while(i<j && strcmp(s[i],x)<=0) ++i; 17 strcpy(s[j],s[i]); 18 } 19 strcpy(s[i],x); 20 return i; 21 } 22 void quick(int l,int r) 23 { 24 if(l<r){ 25 int temp=quicksort(l,r); 26 quick(l,temp-1); 27 quick(temp+1,r); 28 } 29 } 30 int main() 31 { 32 char c; 33 int k=0; 34 int num=0; 35 int flag=1; 36 while(scanf("%c",&c)!=EOF){ 37 if(isalpha(c)){ 38 if(flag) 39 flag=0; 40 if(isupper(c)) 41 s[k][num++]=tolower(c); 42 else 43 s[k][num++]=c; 44 } 45 else{ 46 if(!flag){ 47 //printf("%s\n",s[k]); 48 flag=1; 49 num=0; 50 k++; 51 } 52 } 53 } 54 quick(0,k-1); //PE的原因在这里、多加了一组字符 55 //for(int i=0;i<=k;++i){ 56 // for(int j=0;j<strlen(s[i]);++j) 57 // printf("%d ",s[i][j]); 58 // printf("\n"); 59 //} 60 for(int i=0;i<k;++i) 61 if(strcmp(s[i],s[i+1])) printf("%s\n",s[i]); 62 return 0; 63 } 64 //果然找到错误原因了、 65 //还是在统计单词数量环节出了问题、 66 //读单词并不严谨、如果一开始就读到空格之类的字符、 67 //那么起始单词的位置就是1、 68 //然而我是从0开始排序的、所以会多少出一个空行、 69 //这就是无限PE的原因、
UVA 644 Immediate Decodability
题意:给你一些字符、问其中是不是有一些字符是某个字符的前缀、每一组数据以出现字符9结束、
思路:按字符串长度排一个序、然后从小往大开始比较、
1 #include<cmath> 2 #include<cstring> 3 #include<cstdio> 4 #include<string> 5 #include<algorithm> 6 #include<iostream> 7 using namespace std; 8 struct Str 9 { 10 string ans; 11 int len; 12 bool operator < (Str a)const //重载运算符、 13 { 14 return len<a.len; 15 } 16 }str[20]; 17 int main() 18 { 19 int k=0; 20 int t=1; 21 while(cin >> str[k].ans){ 22 str[k].len=str[k].ans.size(); 23 ++k; 24 while(cin >> str[k].ans && str[k].ans[0]!='9'){ 25 str[k].len=str[k].ans.size(); 26 ++k; 27 } 28 sort(str,str+k); 29 int flag=0; 30 for(int l,j,i=0;i<k;++i){ 31 for(j=i+1;j<k;++j){ 32 for(l=0;l<str[i].len;++l) 33 if(str[i].ans[l]!=str[j].ans[l]) break; 34 if(l>=str[i].len) flag=1; 35 if(flag) break; 36 } 37 if(flag) break; 38 } 39 //判断判反了又WA一发、 40 if(!flag) printf("Set %d is immediately decodable\n",t++); 41 else printf("Set %d is not immediately decodable\n",t++); 42 k=0; //k没归0 WA一发、 43 } 44 }
UVA 10115 Automatic Editing
题意:给你n字符串以及对应的变化后的字符串、最后再给你一个字符串、然你在这个字符串中找到题目开始所给的n个字符串中的一个、然后变化、这里变化有这么一个规则,从所给n个字符串中从1遍历到n ,如果在第m个单词搜索的时候可以变化、那么就将字符串变化、然后重新遍历变化后的字符串、具体还是看代码吧、
思路:看代码吧、
1 #include<cmath> 2 #include<cstdio> 3 #include<cstring> 4 int n,len; 5 char find[15][100]; 6 char rep[15][100]; 7 char str[305]; 8 int main() 9 { 10 while(scanf("%d",&n)!=EOF&&n) { 11 getchar(); 12 for(int i=0; i<n; ++i) { 13 gets(find[i]); 14 gets(rep[i]); 15 } 16 gets(str); 17 len=strlen(str); //len记录的是字符串的总长度、 18 for(int j,i=0; i<n; ++i) { 19 int k=0; 20 int c=strlen(find[i]); 21 for(j=0; j<len; ++j) { 22 int v,u; 23 for(v=0,u=j; v<c&&u<len; ++v,++u) 24 if(str[u]!=find[i][v]) break; 25 if(v==c) break; //匹配成功、 26 } 27 if(j<len) { 28 int d=strlen(rep[i]); 29 if(d>c) { //增加字符 30 int ans=d-c; 31 for(int l=len; l>=j+c; l--) //后移、 32 str[l+ans]=str[l]; 33 int p=0; 34 for(int l=j; l<j+d; ++l,p++) 35 str[l]=rep[i][p]; 36 len+=ans; 37 } else if(d==c) for(int l=j,p=0; l<=j+c-1; ++l) str[l]=rep[i][p++]; 38 else { 39 int ans=c-d; //减少字符、 40 for(int l=j+c; l<=len; ++l) //前移、 41 str[l-ans]=str[l]; 42 int p=0; 43 for(int l=j; l<j+d; ++l,++p) 44 str[l]=rep[i][p]; 45 len-=ans; 46 } 47 --i; 48 } 49 } 50 printf("%s\n",str); 51 } 52 return 0; 53 }
这9道题中 有5道士本次周计划中完成的、
总结一下做UVAOJ的一些经验把、
首先UVA的题目其实不难、主要考察看题是否仔细(就是在考英语嘛!!),比如一些规则、还有格式控制、
如果没把题目理解清楚、最好还是不要敲代码、
另外做UVA一定一定要把题目看完、不要漏信息、尤其是input和output其中肯定有一些可以解开你疑惑的信息、
还有就是多努力吧、