【c/c++算法刷题笔记】—— 洛谷闯关1.4 简单字符串


【前言】今天也是学到东西的一天~道阻且长,加油喽!

P1055 ISBN号码

题目描述

每一本正式出版的图书都有一个ISBN号码与之对应,ISBN码包括99位数字、11位识别码和33位分隔符,其规定格式如x-xxx-xxxxx-x,其中符号-就是分隔符(键盘上的减号),最后一位是识别码,例如0-670-82162-4就是一个标准的ISBN码。ISBN码的首位数字表示书籍的出版语言,例如00代表英语;第一个分隔符-之后的三位数字代表出版社,例如670670代表维京出版社;第二个分隔符后的五位数字代表该书在该出版社的编号;最后一位为识别码。
你的任务是编写程序判断输入的ISBN号码中识别码是否正确,如果正确,则仅输出Right;如果错误,则输出你认为是正确的ISBN号码。

输入格式
一个字符序列,表示一本书的ISBN号码(保证输入符合ISBN号码的格式要求)。

输出格式
一行,假如输入的ISBN号码的识别码正确,那么输出Right,否则,按照规定的格式,输出正确的ISBN号码(包括分隔符-)。

样例

输入
0-670-82162-4

输出
Right

输入
0-670-82162-0

输出
0-670-82162-4

笔记
  1. (j++)/ j++ 加不加括号一样 的
  2. (str[i]-'0') * ++j先加再乘;(str[i]-'0') * (j++)先乘再加
  3. 分情况讨论时要逻辑清晰不能丢掉情况
代码
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<cmath>
using namespace std;

int main(){
	string str;
	cin>>str;
	int sum=0,ans=0,j=0;
	for(int i=0;i<12;i++){
		if(i==1 || i==5 || i==11) continue;
		sum+=(str[i]-'0')*++j;
	}
	if((sum%11==10 && str[12]=='X') || (sum%11==str[12]-'0')) cout<<"Right"<<endl;
	else {
		
		str[12]=sum%11==10?'X':sum%11+'0';
		cout<<str<<endl;	
	}
	return 0;
} 

P1200 你的飞碟在这儿Your Ride Is Here

题目描述

众所周知,在每一个彗星后都有一只UFO。这些UFO时常来收集地球上的忠诚支持者。不幸的是,他们的飞碟每次出行都只能带上一组支持者。
你的任务是写一个程序,通过小组名和彗星名来决定这个小组是否能被那颗彗星后面的UFO带走。

小组名和彗星名都以下列方式转换成一个数字:最终的数字就是名字中所有字母的积,其中AA是11,ZZ是2626。例如,USACO小组就是 21×19×1×3×15=17955。如果小组的数字 mod47 等于彗星的数字mod47,你就得告诉这个小组需要准备好被带走!(记住a mod b”是a除以 b 的余数;34 mod 10 等于 44)

写出一个程序,读入彗星名和小组名并算出用上面的方案能否将两个名字搭配起来,如果能搭配,就输出“GO”,否则输出“STAY”。小组名和彗星名均是没有空格或标点的一串大写字母(不超过6个字母)。

输入格式
第1行:一个长度为11到66的大写字母串,表示彗星的名字。

第2行:一个长度为11到66的大写字母串,表示队伍的名字。

输出格式

样例

输入 #1
COMETQ
HVNGAT

输出 #1
GO

输入 #2
ABSTAR
USACO

输出 #2
STAY

笔记

见代码

代码
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<cmath>
using namespace std;

int main(){
	string str1,str2;
	long sum=1;
	int a,b=0;
	cin>>str1>>str2;
	for(int i=0;i<str1.size();i++){
		sum*=str1[i]-'A'+1;
	} 
	a=sum%47;
	sum=1;
	for(int i=0;i<str2.size();i++){
		sum*=str2[i]-'A'+1;
	}
	b=sum%47;
	a==b?cout<<"GO":cout<<"STAY"<<endl;
	return 0;
} 

P1308 统计单词数

题目描述

一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数。

现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给定的文章中出现的次数和第一次出现的位置。注意:匹配单词时,不区分大小写,但要求完全匹配,即给定单词必须与文章中的某一独立单词在不区分大小写的情况下完全相同(参见样例1 ),如果给定单词仅是文章中某一单词的一部分则不算匹配(参见样例2 )。

输入格式
共22行。

第11行为一个字符串,其中只含字母,表示给定单词;

第22行为一个字符串,其中只可能包含字母和空格,表示给定的文章。

输出格式
一行,如果在文章中找到给定单词则输出两个整数,两个整数之间用一个空格隔开,分别是单词在文章中出现的次数和第一次出现的位置(即在文章中第一次出现时,单词首字母在文章中的位置,位置从00 开始);如果单词在文章中没有出现,则直接输出一个整数-1−1。

样例

输入 #1
To
to be or not to be is a question

输出 #1
2 0

输入 #2
to
Did the Ottoman Empire lose its power at that time

输出 #2
-1

笔记
  1. 不区分大小写解决方案:全部变为小写
	string lower(string s){
	for(long i=0;i<s.size();i++){
		s[i]=tolower(s[i]);	//tolower / toupper 库函数
	}
	return s;
}
  1. 完全匹配 解决方案:判读匹配字符串前后是否为空格,边界只考虑一边
  2. getchargetline 搭配使用 ,getchar() 吸收换行符 ,不用额外头文件
代码
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<string>
#include<cmath>
using namespace std;

string lower(string s){
	for(long i=0;i<s.size();i++){
		s[i]=tolower(s[i]);
	}
	return s;
}

int main(){
	string str1,str2;
	cin>>str1;
	getchar();
	getline(cin,str2);
	str1=lower(str1); 
	str2=lower(str2);
	int pos=str2.find(str1,pos),ans=0,no1=0;
	while(pos>=0){
	 
		int idx_fnt=pos-1,idx_rear=str1.size()+pos;
		if((pos==0&&str2[idx_rear]==' ') || (str2[idx_fnt]==' '&&idx_rear==str2.size())
			|| (str2[idx_fnt]==' '&&str2[idx_rear]==' ')){
					ans++;
					if(ans==1) no1=pos; 
			}
		pos=str2.find(str1,pos+1);	
	}
	if(ans==0) cout<<-1<<endl;
	else cout<<ans<<" "<<no1<<endl;
	return 0;
} 


P1553 数字反转(升级版)

题目描述

给定一个数,请将该数各个位上数字反转得到一个新数。

这次与NOIp2011普及组第一题不同的是:这个数可以是小数,分数,百分数,整数。

整数反转是将所有数位对调。

小数反转是把整数部分的数反转,再将小数部分的数反转,不交换整数部分与小数部分。

分数反转是把分母的数反转,再把分子的数反转,不交换分子与分母。

百分数的分子一定是整数,百分数只改变数字部分。

输入格式
一个数 ss

输出格式
一个数,即 ss 的反转数

样例

输入 #1
5087462

输出 #1
2647805

笔记

见代码

代码
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<string>
#include<cmath>
using namespace std;

//反转各个数字 
string rev(string s,int begin,int end){ 
	string ans="";
	for(int i=end-1;i>=begin;i--){
		ans+=s[i];
	}
	return ans;
}

//去除数字前面的0
string del_f(string str){
	for(int i=0;i<str.size();i++) {
		if(str[i]!='0') {
			str=str.substr(i);
			break;
		}
	}
	return str;
}

//去除数字后面的0 
string del_e(string str){
	for(int i=str.size()-1;i>=0;i--){
		if(str[i]!='0'){
			str=str.substr(0,i+1);
			break;
		}
	}
	return str;
}

int main(){
	string str,str1,str2;
	cin>>str;
	int pos;
	if(str.find('.')!=-1){	//需去除整数前面的0,小数后面的0
		pos=str.find('.');
		str1=del_f(rev(str,0,pos));		
		str2=del_e(rev(str,pos+1,str.size()));
		cout<<str1<<"."<<str2<<endl;	
	}
	else if (str.find('/')!=-1){	//需去除分母前面的0,分子前面的0
		pos=str.find('/');
		str1=del_f(rev(str,0,pos));
		str2=del_f(rev(str,pos+1,str.size()));
		cout<<str1<<"/"<<str2<<endl;
	}
	else if(str.find('%')!=-1){	//需去除百分号前整数前面的0
		pos=str.find('%');
		str=del_f(rev(str,0,pos));
		cout<<str<<"%"<<endl;	
	}
	else{		//需去除整数前面的0
		cout<<del_f(rev(str,0,str.size()))<<endl;	
	}
	
	return 0;
} 


P1598 垂直柱状图

题目描述

题目描述
写一个程序从输入文件中去读取四行大写字母(全都是大写的,每行不超过100个字符),然后用柱状图输出每个字符在输入文件中出现的次数。严格地按照输出样例来安排你的输出格式。

输入格式
四行字符,由大写字母组成,每行不超过100个字符

输出格式
由若干行组成,前几行由空格和星号组成,最后一行则是由空格和字母组成的。在任何一行末尾不要打印不需要的多余空格。不要打印任何空行。

样例

输入 #1
THE QUICK BROWN FOX JUMPED OVER THE LAZY DOG.
THIS IS AN EXAMPLE TO TEST FOR YOUR
HISTOGRAM PROGRAM.
HELLO!

输出 #1

                            *
                            *
        *                   *
        *                   *     *   *
        *                   *     *   *
*       *     *             *     *   *
*       *     * *     * *   *     * * *
*       *   * * *     * *   * *   * * * *
*     * * * * * *     * * * * *   * * * *     * *
* * * * * * * * * * * * * * * * * * * * * * * * * *
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
笔记
  1. 输出 acsll 对应的符号 应转换成字符格式 char c = 65; cout<<c;
  2. getchar();不用吸收 换行。循环4次,每次读取一行,自动屏蔽了空格不需要单独处理
代码
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;

int words[26]; 

int main(){
	string str;
	int max=0;
	for(int j=0;j<4;j++){
		getline(cin,str);
		for(int i=0;i<str.size();i++){
			if(str[i]>='A'&&str[i]<='Z') words[str[i]-'A']++;
			if(words[str[i]-'A']>max) max=words[str[i]-'A'];
		}
	}
	int pale[max][26]={0};
	for(int j=0;j<26;j++){
		for(int i=max-words[j];i<max;i++){
			pale[i][j]=1;	
		}
	} 
	for(int i=0;i<max;i++){
		for(int j=0;j<26;j++){
			pale[i][j]==1?cout<<"* ":cout<<"  ";
		}
		cout<<endl;
	}
	
	for(int i=0;i<26;i++){
		char c='A'+i;
		cout<<c<<" ";
	}
	return 0;
} 


P1914 小书童——密码

题目描述

题目背景
某蒟蒻迷上了“小书童”,有一天登陆时忘记密码了(他没绑定邮箱or手机),于是便把问题抛给了神犇你。

题目描述
蒟蒻虽然忘记密码,但他还记得密码是由一个字符串组成。密码是由原文字符串(由不超过 50 个小写字母组成)中每个字母向后移动 nn 位形成的。z 的下一个字母是 a,如此循环。他现在找到了移动前的原文字符串及 nn,请你求出密码。

样例

输入格式
第一行:n。第二行:未移动前的一串字母

输出格式
一行,是此蒟蒻的密码

笔记
  • 不可以while(n--),会改变n ,下次就不能使用了
代码
#include<iostream>
#include<string>
using namespace std;

int main(){
	int n;
	string str;
	cin>>n>>str;
	for(int i=0;i<str.size();i++){
		for(int j=0;j<n;j++){
			if(str[i]=='z') str[i]='a';
			else str[i]=str[i]+1;
		}
	}
	cout<<str<<endl;
	return 0;
} 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值