noi题库(noi.openjudge.cn) 1.7编程基础之字符串T21——T30

T21:单词替换

描述

输入一个字符串,以回车结束(字符串长度<=100)。该字符串由若干个单词组成,单词之间用一个空格隔开,所有单词区分大小写。现需要将其中的某个单词替换成另一个单词,并输出替换之后的字符串。

输入

输入包括3行,
第1行是包含多个单词的字符串 s;
第2行是待替换的单词a(长度 <= 100);
第3行是a将被替换的单词b(长度 <= 100).

s, a, b 最前面和最后面都没有空格.

输出

输出只有 1 行,将s中所有单词a替换成b之后的字符串。

样例输入
You want someone to help you
You
I
样例输出
I want someone to help you

样例

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 char s[501],a[501],b[501];
 6 string f[101];
 7 bool v[101];
 8 int main()
 9 {
10     gets(s);gets(a);gets(b);
11     int k=1,l=strlen(s);
12     for(int i=0;i<l;i++)
13     {
14         if(s[i]!=‘ ‘)
15          f[k]+=s[i];
16         else k++;
17     }
18     for(int i=1;i<=k;i++)
19     {
20         if(f[i]==a) cout<<b<<‘ ‘;
21         else cout<<f[i]<<‘ ‘;
22     }
23 }

T22 紧急措施

描述

近日,一些热门网站遭受黑客入侵,这些网站的账号、密码及email的数据惨遭泄露。你在这些网站上注册若干账号(使用的用户名不一定相同),但是注册时使用了相同的email。你此时拿到了那份泄露的数据,希望尽快将自己的密码更改。策略如下:根据email找到你的用户名和密码,然后更改密码。更改的规则为:小写和大写交换,非字母字符保持不变。

输入

第一行为你的email地址,长度不超过50个字符且只包含字母、数字和‘@’符号。
第二行为账号数N,N(0 < N < 10000)。
接下来N行,每行表示一个账号,格式为:
用户名 密码 email
它们之间用单个空格分开。用户名、密码、email均不含空格,且长度不超过50个字符。

输出

有若干行,每行为你的一个账号,包括:你的账号,修改后的密码(之间用单个空格分隔)。
如果没有你的账号,则输出empty。

样例输入
样例输入1:
[email protected]
5
helloKitty iLoveCats [email protected]
2012 maya2012 [email protected]
KittyCat 5iKitty [email protected]
program password [email protected]
whoAmi Feb.29$ [email protected]

样例输入2:
[email protected]
1
2012 maya2012 [email protected]
样例输出
样例输出1:
helloKitty IlOVEcATS
KittyCat 5IkITTY
whoAmi fEB.29$

样例输出2:
empty

样例

 1 #include<cstring>
 2 #include<iostream>
 3 using namespace std;
 4 string me,usename,password,email;
 5 int n;
 6 bool ok;
 7 int main()
 8 {
 9     cin>>me;cin>>n;
10     for(int i=1;i<=n;i++)
11     {
12         cin>>usename>>password>>email;
13         if(me==email)
14         {
15             ok=true;
16             cout<<usename<<‘ ‘;
17             for(int j=0;j<password.size();j++)
18               if(password[j]>=‘a‘&&password[j]<=‘z‘) cout<<char(password[j]-32);
19               else if(password[j]>=‘A‘&&password[j]<=‘Z‘) cout<<char(password[j]+32);
20               else cout<<password[j];
21             cout<<endl;
22         }
23     }
24     if(!ok) cout<<"empty";
25 }

T23 过滤多余的空格

描述

一个句子中也许有多个连续空格,过滤掉多余的空格,只留下一个空格。

输入

一行,一个字符串(长度不超过200),句子的头和尾都没有空格。输出过滤之后的句子。

样例输入
Hello      world.This is    c language.
样例输出
Hello world.This is c language.

样例

每相邻连个判断一次,若相邻两个都是空格,则删除后面的,删除可以通过bool实现

 1 #include<cstring>
 2 #include<iostream>
 3 #include<cstdio>
 4 using namespace std;
 5 char a[501];
 6 bool b[501];
 7 int main()
 8 {
 9     gets(a);
10     for(int i=0;i<strlen(a);i++)
11           if(a[i]==‘ ‘&&a[i+1]==‘ ‘) b[i+1]=true;//true代表为多余的空格
12     for(int i=0;i<strlen(a);i++)
13      {
14          if(b[i]) continue;
15          cout<<a[i];
16      }
17 }

T24 单词的长度

描述

输入一行单词序列,相邻单词之间由1个或多个空格间隔,请对应地计算各个单词的长度。

注意,如果有标点符号(如连字符,逗号),标点符号算作与之相连的词的一部分。没有被空格间开的符号串,都算作单词。


输入

一行单词序列,最少1个单词,最多300个单词,单词之间用至少1个空格间隔。单词序列总长度不超过1000。

输出

依次输出对应单词的长度,之间以逗号间隔。

注意中间可能有相连的好几个空格,排除方法参见下方T25题解

样例输入
She was born in 1990-01-02  and  from Beijing city.
样例输出
3,3,4,2,10,3,4,7,5

样例

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 char a[2001];
 6 int s;
 7 int main()
 8 {
 9     gets(a);
10     int l=strlen(a);
11     for(int i=0;i<l;i++)
12     {
13         if(a[i]!=‘ ‘) s++;
14         else if(a[i]==‘ ‘&&a[i-1]!=‘ ‘) //排除掉多个空格相连的情况
15         {
16             cout<<s<<‘,‘;
17             s=0;
18         }
19     }
20     cout<<s;
21 }

T25 最长最短单词

描述

输入1行句子(不多于200个单词,每个单词长度不超过100),只包含字母、空格和逗号。单词由至少一个连续的字母构成,空格和逗号都是单词间的间隔。

试输出第1个最长的单词和第1个最短单词。

输入

一行句子。

输出

两行输出:
第1行,第一个最长的单词。
第2行,第一个最短的单词。

样例输入
I am studying Programming language C in Peking University
样例输出
Programming
I

样例

如果所有单词长度相同,那么第一个单词既是最长单词也是最短单词。

注意中间可能有相连的好几个空格或逗号

确定一个单词,排除相连的几个空格或逗号的干扰的方法:若是2个单词之间的空格,则满足(a[i]==‘ ‘||a[i]==‘,‘)&&(a[i-1]!=‘ ‘&&a[i-1]!=‘,‘),即这一位是空格或逗号,上一位既不是空格,又不是逗号,本方法同样适用T24

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 char a[3001];
 6 int s;
 7 int max_len,max_num,min_len=200,min_num;//分别代表含义:最长单词的长度,最长单词是第几个单词,最短单词的长度,最短单词是第几个单词
 8 string f[201];//存储断开的单词
 9 int main()
10 {
11     gets(a);
12     int k=1;//要存储第几个单词
13     int l=strlen(a);
14     for(int i=0;i<l;i++)
15     {
16         if(a[i]!=‘ ‘&&a[i]!=‘,‘) f[k]+=a[i],s++;//s代表当前单词长度
17         else if((a[i]==‘ ‘||a[i]==‘,‘)&&(a[i-1]!=‘ ‘&&a[i-1]!=‘,‘))
18         {
19             if(s>max_len) {max_len=s;max_num=k;}
20             if(s<min_len) {min_len=s;min_num=k;}
21             s=0;
22             k++;
23         }
24     }
25     if(s>max_len) {max_len=s;max_num=k;}//由于只循环到strlen(a)-1,所以最后一个单词在上述循环中是无法被记录的
26     if(s<min_len) {min_len=s;min_num=k;}
27     cout<<f[max_num]<<endl<<f[min_num];
28 }

T26:字符串最大跨距

描述
有三个字符串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。
输入
三个串:S1, S2, S3,其间以逗号间隔(注意,S1, S2, S3中均不含逗号和空格);
输出
S1和S2在S最大跨距;若在S中没有满足条件的S1和S2,则输出-1。

样例输入
abcd123ab888efghij45ef67kl,ab,ef
样例输出
18

样例

特别注意字符串不交叉

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 char a[301],b[11],c[11],t[11];
 6 char s[401];
 7 int p,la,lb,lc,first,endd;
 8 int find(int k,int w)
 9 {
10     int j=1,i=k,lt;
11     if(w==2)
12     {
13       lt=lb;
14       for(int r=1;r<=lb;r++) t[r]=b[r];
15     }
16     else
17     {
18         lt=lc;
19         for(int r=1;r<=lc;r++) t[r]=c[r];
20     }
21     for(;i<=la,j<=lt;i++,j++)
22         if(a[i]!=t[j]) return 0;
23     if(j-1!=lt) return 0;
24     return k;
25 }
26 int main()
27 {
28     cin>>s;
29     int ls=strlen(s);
30     for(int i=0;i<ls;i++)/输入一整行,再断开
31     {
32         if(s[i]==‘,‘) p++;
33         else if(!p) a[++la]=s[i];
34         else if(p==1) b[++lb]=s[i];
35         else c[++lc]=s[i];
36     }
37     for(int i=1;i<=la;i++)
38     {
39         if(a[i]==b[1]&&!first)  first=find(i,2);//只需要出现的第一个位置,所以!first时才执行
40          if(a[i]==c[1]) endd=max(endd,find(i,3));//需要最后一个位置,所以要取大
41
42     }
43     if(first==0||endd==0||first+lb>endd)   cout<<-1;//first+lb>endd,交叉的情况以及first>endd的情况都是-1
44     else
45     {
46         first+=lb;//first变成最大跨距中的第一个位置
47         cout<<endd-first;//endd为最大跨距中的最后一个位置的后一个。例:字符串abcde中找ab、de,first开始=1,+lb=3,endd=4,ans=end-first=1
48     }
49 }

两大错误:1、没认真读好题,题目里说的是检测条件是s1在s2左边,且不交叉,不是输入字符串的本就具备的条件

2、处理endd时,没加max,忽略了find函数可能返回0,直接赋值有可能用0盖过原来的值

T27 单词翻转
描述

输入一个句子(一行),将句子中的每一个单词翻转后输出。

输入
只有一行,为一个字符串,不超过500个字符。单词之间以空格隔开。
输出
翻转每一个单词后的字符串,单词之间的空格需与原文一致。

样例输入
hello world
样例输出
olleh dlrow

样例

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 using namespace std;
 5 char a[1001],b[1001];
 6 int main()
 7 {
 8     gets(a);
 9     int la=strlen(a);
10     for(int i=0;i<la;i++)
11     {
12         if(a[i]==‘ ‘)
13         {
14             for(int j=b[0];j>0;j--) cout<<b[j];//若多个空格相连,b[0]=0,不会有输出
15             b[0]=0;
16             cout<<‘ ‘;
17         }
18         else b[++b[0]]=a[i];
19     }
20     for(int j=b[0];j>0;j--) cout<<b[j];//若最后一个但此后面没有空格,执行此句输出
21 }

T28 单词倒排

描述

编写程序,读入一行英文(只包含字母和空格,单词间以单个空格分隔),将所有单词的顺序倒排并输出,依然以单个空格分隔。

输入

输入为一个字符串(字符串长度至多为100)。

输出

输出为按要求排序后的字符串。

样例输入
I am a student
样例输出
student a am I

样例

法1:将T27的代码第一重循环改为逆序即可

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 using namespace std;
 5 char a[1001],b[1001];
 6 int main()
 7 {
 8     gets(a);
 9     int la=strlen(a);
10     for(int i=la-1;i>=0;i--)
11     {
12         if(a[i]==‘ ‘)
13         {
14             for(int j=b[0];j>0;j--) cout<<b[j];
15             b[0]=0;
16             cout<<‘ ‘;
17         }
18         else b[++b[0]]=a[i];
19     }
20     for(int j=b[0];j>0;j--) cout<<b[j];
21 }

1

法2:开一个字符二维数组,单个字符单个字符的读入,忽略空格以单词的形式存储,再倒着循环第一维输出每个单词和一个空格

 1 #include<iostream>
 2 using namespace std;
 3 int main()
 4 {
 5   int i;
 6   char a[1002][102];
 7   i=1;
 8   while(cin>>a[i])i++;
 9   for(i--;i>=1;i--)
10   cout<<a[i]<<‘ ‘;
11   return 0;
12 }

2

T29 ISBN号码

描述

每一本正式出版的图书都有一个ISBN号码与之对应,ISBN码包括9位数字、1位识别码和3位分隔符,其规定格式如“x-xxx-xxxxx-x”,其中符号“-”是分隔符(键盘上的减号),最后一位是识别码,例如0-670-82162-4就是一个标准的ISBN码。ISBN码的首位数字表示书籍的出版语言,例如0代表英语;第一个分隔符“-”之后的三位数字代表出版社,例如670代表维京出版社;第二个分隔之后的五位数字代表该书在出版社的编号;最后一位为识别码。

识别码的计算方法如下:

首位数字乘以1加上次位数字乘以2……以此类推,用所得的结果mod 11,所得的余数即为识别码,如果余数为10,则识别码为大写字母X。例如ISBN号码0-670-82162-4中的识别码4是这样得到的:对067082162这9个数字,从左至右,分别乘以1,2,…,9,再求和,即0×1+6×2+??+2×9=158,然后取158 mod 11的结果4作为识别码。

你的任务是编写程序判断输入的ISBN号码中识别码是否正确,如果正确,则仅输出“Right”;如果错误,则输出你认为是正确的ISBN号码。

输入

只有一行,是一个字符序列,表示一本书的ISBN号码(保证输入符合ISBN号码的格式要求)。输出共一行,假如输入的ISBN号码的识别码正确,那么输出“Right”,否则,按照规定的格式,输出

正确的ISBN号码(包括分隔符“-”)。

样例输入
样例 #1:
0-670-82162-4

样例 #2:
0-670-82162-0
样例输出
样例 #1:
Right

样例 #2:
0-670-82162-4

样例

 1 #include<iostream>
 2 using namespace std;
 3 char a[15];
 4 int s;
 5 int main()
 6 {
 7     cin>>a;
 8     int j=1;
 9     for(int i=0;i<=10;i++)
10     {
11         if(a[i]==‘-‘) continue;
12         s+=(a[i]-‘0‘)*j++;
13     }
14     s%=11;
15     if(s<10)
16     {
17         if(a[12]==char(s+48)) cout<<"Right";//数字的值与对应的ascll码相差48
18         else
19          {
20              for(int i=0;i<=11;i++) cout<<a[i];
21              cout<<char(s+48);
22          }
23     }
24     else
25     {
26         if(a[12]==‘X‘) cout<<"Right";
27         else
28          {
29              for(int i=0;i<=11;i++) cout<<a[i];
30              cout<<‘X‘;
31          }
32      }
33 }

T30 字符环

描述

有两个由字符构成的环。请写一个程序,计算这两个字符环上最长连续公共字符串的长度。例如,字符串“ABCEFAGADEGKABUVKLM”的首尾连在一起,构成一个环;字符串“MADJKLUVKL”的首尾连在一起,构成一个另一个环;“UVKLMA”是这两个环的一个连续公共字符串。

输入

一行,包含两个字符串,分别对应一个字符环。这两个字符串之间用单个空格分开。字符串长度不超过255,且不包含空格等空白符。

输出

输出一个整数,表示这两个字符环上最长公共字符串的长度。

样例输入
ABCEFAGADEGKABUVKLM MADJKLUVKL
样例输出
6

样例

这是一个环,环的特点是从任何一个位置转一圈都能回到起点,也就是从任何一个位置开始遍历都能把整个字符串遍历一遍。假设有一个字符串a(从0开始),长度为l,我们可以将a复制一遍接到a的后面,这样以0—l-1的任何一个点,长度为l的区域都是整个字符串,这就实现了环向链的转化。

然后就是枚举区间长度,区间起点、终点比较,因为是求最大,所以可以从两个字符串的长度值较小的开始枚举,依次递减,符合要求就输出,结束程序

 1 #include<cstring>
 2 #include<iostream>
 3 using namespace std;
 4 char a[1111],b[1111];
 5 int main()
 6 {
 7     cin>>a>>b;
 8     int la=strlen(a),lb=strlen(b);
 9     for(int i=0;i<la;i++) a[la+i]=a[i];//断环成链
10     for(int i=0;i<lb;i++) b[lb+i]=b[i];
11     for(int k=min(la,lb);k>=1;k--)//枚举答案可能情况
12      for(int i=0;i<la;i++)//第一个字符串的左端点
13       {
14            int za=i+k-1;//第一个字符串区间长度为k时的右端点
15            for(int j=0;j<lb;j++)//第二个字符串的左端点
16            {
17                int zb=j+k-1;//第二个字符串区间长度为k时的右端点
18                int sa=i,sb=j;
19                bool flag=true;
20                while(sa<=za&&sb<=zb)//比较是否公共
21                {
22                    if(a[sa]!=b[sb])
23                    {
24                        flag=false;
25                        break;
26                 }
27                 else sa++,sb++;
28             }
29             if(flag)
30             {
31                 cout<<k;
32                 return 0;
33             }
34          }
35       }
36 }

时间: 2024-10-09 09:02:33

noi题库(noi.openjudge.cn) 1.7编程基础之字符串T21——T30的相关文章

[NOI题库]1.1题解

今年NOIP居然"各有两道题目从NOI题库中抽取并在原题基础上改动后使用",不好好刷题怎么行. 这是第一篇题解文章,因为题目太水直接上代码了. 1.1编程基础之输入输出 01 Hello, World! 根据题意直接输出"Hello, World!"即可. #include <iostream> using namespace std; int main() { cout<<"Hello, World!"<<e

NOI题库 1768最大子矩阵 题解

NOI题库 1768最大子矩阵  题解 总时间限制: 1000ms 内存限制: 65536kB 描述 已知矩阵的大小定义为矩阵中所有元素的和.给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵. 比如,如下4 * 4的矩阵 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2 的最大子矩阵是 9 2 -4 1 -1 8 这个子矩阵的大小是15. 输入   输入是一个N * N的矩阵.输入的第一行给出N (0 < N <= 100).再后面的若干行中,依

【NOI题库】9269:Big String超级字符串

传送门:http://noi.openjudge.cn/ch0207/9269/ //------------------------------------题目内容-------------------------------------- 9269:Big String超级字符串 总时间限制: 10000ms 单个测试点时间限制: 1000ms 内存限制: 131072kB 描述 fish在无数次oi竞赛的狱炼之后,悟出一个真理,往往越容易的题目,陷阱越深.由此,fish创作了这道题目. f

[NOI题库]1.3编程基础之算术表达式与顺序执行 题解(一)

01 A+B问题 经典的A+B Problem——各大题库上的首题.读入$a,b$,输出$a+b$. #include <iostream> using namespace std; int main() { int a,b; cin>>a>>b; cout<<a+b<<endl; return 0; } 01.cpp 02 计算(a+b)*c的值 读入$a,b,c$,输出$c(a+b)$. #include <iostream> u

noi题库(noi.openjudge.cn) 1.8编程基础之多维数组T11——T20

T11 图像旋转 描述 输入一个n行m列的黑白图像,将它顺时针旋转90度后输出. 输入 第一行包含两个整数n和m,表示图像包含像素点的行数和列数.1 <= n <= 100,1 <= m <= 100.接下来n行,每行m个整数,表示图像的每个像素点灰度.相邻两个整数之间用单个空格隔开,每个元素均在0~255之间. 输出 m行,每行n个整数,为顺时针旋转90度后的图像.相邻两个整数之间用单个空格隔开. 样例输入 3 3 1 2 3 4 5 6 7 8 9 样例输出 7 4 1 8 5

noi题库(noi.openjudge.cn) 1.5编程基础之循环控制T37——T38

T37 雇佣兵 描述 雇佣兵的体力最大值为M,初始体力值为0.战斗力为N.拥有X个能量元素. 当雇佣兵的体力值恰好为M时,才可以参加一个为期M天的战斗期,战斗期结束体力值将为0.在同一个战斗期内,雇佣兵每连续战斗n天,战斗力就会上升1点,n为当前战斗期开始时的战斗力. 一个战斗期结束后,雇佣兵需要用若干个能量元素使其体力恢复到最大值M,从而参加下一个战斗期.每个能量元素恢复的体力值不超过当前的战斗力.每个能量元素只能使用一次. 请问:雇佣兵的战斗力最大可以到达多少. 输入 一行包括三个整数M.N

noi题库(noi.openjudge.cn) 1.11编程基础之二分查找T01、02、04

T01 查找最接近的元素 描述 在一个非降序列中,查找与给定值最接近的元素. 输入 第一行包含一个整数n,为非降序列长度.1 <= n <= 100000.第二行包含n个整数,为非降序列各元素.所有元素的大小均在0-1,000,000,000之间.第三行包含一个整数m,为要询问的给定值个数.1 <= m <= 10000.接下来m行,每行一个整数,为要询问最接近元素的给定值.所有给定值的大小均在0-1,000,000,000之间. 输出 m行,每行一个整数,为最接近相应给定值的元素

noi题库(noi.openjudge.cn) 3.9数据结构之C++STL T1——T2

T1 1806:词典 描述 你旅游到了一个国外的城市.那里的人们说的外国语言你不能理解.不过幸运的是,你有一本词典可以帮助你. 输入首先输入一个词典,词典中包含不超过100000个词条,每个词条占据一行.每一个词条包括一个英文单词和一个外语单词,两个单词之间用一个空格隔开.而且在词典中不会有某个外语单词出现超过两次.词典之后是一个空行,然后给出一个由外语单词组成的文档,文档不超过100000行,而且每行只包括一个外语单词.输入中出现单词只包括小写字母,而且长度不会超过10.输出在输出中,你需要把

noi题库(noi.openjudge.cn) 1.9编程基础之顺序查找T01——T05

T01 查找特定元素的值 描述 在一个序列(下标从1开始)中查找一个给定的值,输出第一次出现的位置. 输入 第一行包含一个正整数n,表示序列中元素个数.1 <= n <= 10000.第二行包含n个整数,依次给出序列的每个元素,相邻两个整数之间用单个空格隔开.元素的绝对值不超过10000.第三行包含一个整数x,为需要查找的特定值.x的绝对值不超过10000. 输出 若序列中存在x,输出x第一次出现的下标:否则输出-1. 样例输入 5 2 3 6 7 3 3 样例输出 2 样例 1 #inclu