【洛谷题单】洛谷入门5 字符串

全部题单目录:
【洛谷题单】洛谷入门1 顺序结构
【洛谷题单】洛谷入门2 分支结构
【洛谷题单】洛谷入门3 循环结构
【洛谷题单】洛谷入门4 数组

【洛谷题单】洛谷入门5 字符串

洛谷入门5 字符串

P5733【深基6.例1】自动修正

题目描述

大家都知道一些办公软件有自动将字母转换为大写的功能。输入一个长度不超过 100 100 100 且不包括空格的字符串。要求将该字符串中的所有小写字母变成大写字母并输出。

输入格式:
输入一行,一个字符串。

输出格式:
输出一个字符串,即将原字符串中的所有小写字母转化为大写字母。

样例
样例输入

Luogu4!

样例输出

LUOGU4!

1 熟记特殊ASCII码对应的数值 A = 65 a = 97 z = 122

AC代码

#include<iostream>
#include<string.h>
using namespace std;

int main()
{
	string input;
	cin >> input;
	char letter;
	
	for(int i = 0; i < input.length(); i++)
	{
		if(!(input[i] - 0 >= 'a' && input[i] - 0 <= 'z'))
			cout << input[i];
		else
		{
			letter = input[i] - 32;
			cout << letter;
		}
	}
	
	return 0;
} 

P1914 小书童——凯撒密码

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

题目描述

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

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

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

样例
样例输入

1
qwe

样例输出

rxf

提示:
字符串长度 ≤ 50 \le 50 50 1 ≤ n ≤ 26 1 \leq n \leq 26 1n26

AC代码

#include<iostream>
using namespace std;
#include<string.h>
int main()
{
	string input;
	int n;
	char letter;
	
	cin >> n;
	cin >> input;
	
	for(int i = 0; i < input.length(); i++)
	{
		if(input[i] + n > 122)
		{
			letter = input[i] + n - 26;
			cout << letter;
		}
		else 
		{
			letter = input[i] + n;
			cout << letter;
		}
	}	
	
	return 0;
} 

P1125 [NOIP2008 提高组] 笨小猴

题目描述

笨小猴的词汇量很小,所以每次做英语选择题的时候都很头疼。但是他找到了一种方法,经试验证明,用这种方法去选择选项的时候选对的几率非常大!

这种方法的具体描述如下:假设 maxn \text{maxn} maxn 是单词中出现次数最多的字母的出现次数, minn \text{minn} minn 是单词中出现次数最少的字母的出现次数,如果 maxn − minn \text{maxn}-\text{minn} maxnminn 是一个质数,那么笨小猴就认为这是个 Lucky Word,这样的单词很可能就是正确的答案。

输入格式:
一个单词,其中只可能出现小写字母,并且长度小于 100 100 100

输出格式:
共两行,第一行是一个字符串,假设输入的的单词是 Lucky Word,那么输出 Lucky Word,否则输出 No Answer

第二行是一个整数,如果输入单词是 Lucky Word,输出 maxn − minn \text{maxn}-\text{minn} maxnminn 的值,否则输出 0 0 0

样例
样例输入

error

样例输出

Lucky Word
2

样例
样例输入

olympic

样例输出

No Answer
0

提示:
【输入输出样例 1 解释】
单词 error 中出现最多的字母 r \texttt r r 出现了 3 3 3 次,出现次数最少的字母出现了 1 1 1 次, 3 − 1 = 2 3-1=2 31=2 2 2 2 是质数。
【输入输出样例 2 解释】
单词 olympic 中出现最多的字母 i \texttt i i 出现了 1 1 1 次,出现次数最少的字母出现了 1 1 1 次, 1 − 1 = 0 1-1=0 11=0 0 0 0 不是质数。
noip2008 提高第一题

1 质数进行比较的时候,0 1 2都要进行特殊处理

0 1不是质数,需要事先进行声明
2是质数,需要在循环中进行边界条件的稍微改动

for(int i = 2; i < int(sqrt(number) + 1); i++)
//如果不进行强制类型转换会导致浮点数的精度偏差问题
//或者
for(int i = 2; i <= sqrt(number); i++)

2 sort函数进行比较 sort(a, a + 10)

a为数组名 10为比较10个数

AC代码

#include<iostream>
#include<string.h> 
#include<algorithm>
#include<math.h>
using namespace std;

int number = 0;

bool cmp(int x, int y)
{
	return x > y;
}

bool isPrime(int minum)
{
	if(minum == 0 || minum == 1)
		return false;
		
	for(int i = 2; i < int(sqrt(minum) + 1); i++)
	{
		if(minum % i == 0)
			return false;
	}
	
	return true;
}

bool InArray(char* array, char letter)
{
	for(int i = 0; i < number; i++)
	{
		if(array[i] == letter)
			return true;
	}
	
	return false; 
} 
int main()
{
	string input;
	cin >> input;
	int count[input.length()] = {0};
	int max, min, minum;
	char letter[input.length()];
	
	for(int i = 0; i < input.length(); i++)
	{
		if(!InArray(letter, input[i]))
		{
			letter[number] = input[i];
			
			for(int j = i; j < input.length(); j++)
			{
				if(input[j] == input[i])
					count[number]++;
			}
			
			number++;
		}
	}
	
	//cout << number << endl;
	
//	for(int i = 0; i < number; i++)
//	{
//		cout << letter[i] << ' ' << count[i] << endl;
//	}
	
	sort(count, count + number);
	max = count[number - 1];
	min = count[0];
	minum = max - min;
	
	if(isPrime(minum))
	{
		cout << "Lucky Word" << '\n' << minum;
	}
	else
		cout << "No Answer" << '\n' << 0;
	
	return 0;
}

P1957 口算练习题

题目描述

王老师正在教简单算术运算。细心的王老师收集了 i i i 道学生经常做错的口算题,并且想整理编写成一份练习。 编排这些题目是一件繁琐的事情,为此他想用计算机程序来提高工作效率。王老师希望尽量减少输入的工作量,比如 5+8 \texttt{5+8} 5+8 的算式最好只要输入 5 \texttt 5 5 8 \texttt 8 8,输出的结果要尽量详细以方便后期排版的使用,比如对于上述输入进行处理后输出 5+8=13 \texttt{5+8=13} 5+8=13 以及该算式的总长度 6 6 6。王老师把这个光荣的任务交给你,请你帮他编程实现以上功能。

输入格式:
第一行一个整数 i i i
接着的 i i i 行为需要输入的算式,每行可能有三个数据或两个数据。
若该行为三个数据则第一个数据表示运算类型, a \texttt a a 表示加法运算, b \texttt b b 表示减法运算, c \texttt c c 表示乘法运算,接着的两个数据表示参加运算的运算数。
若该行为两个数据,则表示本题的运算类型与上一题的运算类型相同,而这两个数据为运算数。

输出格式:
输出 2 × i 2\times i 2×i 行。对于每个输入的算式,输出完整的运算式及结果,第二行输出该运算式的总长度。

样例
样例输入

4
a 64 46
275 125
c 11 99
b 46 64

样例输出

64+46=110
9
275+125=400
11
11*99=1089
10
46-64=-18
9

提示
【数据规模与约定】
对于 50 % 50\% 50% 的数据,输入的算式都有三个数据,第一个算式一定有三个数据。
对于所有数据, 0 < i ≤ 50 0<i\leq 50 0<i50,运算数为非负整数且小于 10000 10000 10000

1 多行输入 getline()会有一定的问题

尤其是第一行是单个字符的时候尽量不要再使用getline了

2 使用scanf(" %c", &char)

在读取char之前空一个空格,会自动跳过所有前导空白字符,包括换行、空格、制表符,对于前面有换行的读取非常有用!

3 使用ungetc(char, stdin)

可以将已经读取的单个字符退回到输入流

4 使用to_string(number).length()可以直接求出数字的位数,而不用进行循环处理

AC代码

#include<iostream>
using namespace std;
#include<string.h>
#include<math.h>

int main()
{
	int time;
	scanf("%d\n", &time);
		
	char record, operation;
	int ope1, ope2, answer;
	
	while(time--)
	{
		if((scanf(" %c", &record)) && (record >= 'a' && record <= 'c'))
		{
			operation = record;
		}
		else
		{
			ungetc(record, stdin);
		} 
		
		scanf("%d %d", &ope1, &ope2);
		//string number1, number2;
		//int count1 = 1, count2 = 1;

		int i = 0;
		
		//cout << "输出" << line << endl; 
				
		
		if(operation == 'a')
		{
			answer = ope1 + ope2;
			
			cout << ope1 << '+' << ope2 << '=' << answer << '\n';
			
			cout << to_string(ope1).length() + to_string(ope2).length() + to_string(answer).length() + 2; 
		}
		
		if(operation == 'b')
		{
			answer = ope1 - ope2;
			
			cout << ope1 << '-' << ope2 << '=' << answer << '\n';
			
			cout << to_string(ope1).length() + to_string(ope2).length() + to_string(answer).length() + 2; 
		}	
			
	   if(operation == 'c')
		{
			answer = ope1 * ope2;
			cout << ope1 << '*' << ope2 << '=' << answer << '\n';
			
			cout << to_string(ope1).length() + to_string(ope2).length() + to_string(answer).length() + 2; 
		}	
		
		if(time > 0)
			cout << endl;
	}
	
	return 0;
} 

P5015 [NOIP2018 普及组] 标题统计

题目背景:
NOIP2018 普及组 T1

题目描述

凯凯刚写了一篇美妙的作文,请问这篇作文的标题中有多少个字符? 注意:标题中可能包含大、小写英文字母、数字字符、空格和换行符。统计标题字符数时,空格和换行符不计算在内。

输入格式:
输入文件只有一行,一个字符串 s s s

输出格式:
输出文件只有一行,包含一个整数,即作文标题的字符数(不含空格和换行符)。

样例
样例输入

234

样例输出

3

样例
样例输入

Ca 45

样例输出

4

提示:
样例 1 说明:
标题中共有 3 个字符,这 3 个字符都是数字字符。

样例 2 说明:
标题中共有 $ 5$ 个字符,包括 1 1 1 个大写英文字母, 1 1 1 个小写英文字母和 2 2 2 个数字字符, 还有 1 1 1 个空格。由于空格不计入结果中,故标题的有效字符数为 4 4 4 个。

数据规模与约定:
规定 ∣ s ∣ |s| s 表示字符串 s s s 的长度(即字符串中的字符和空格数)。 对于 40 % 40\% 40% 的数据, 1 ≤ ∣ s ∣ ≤ 5 1 ≤ |s| ≤ 5 1s5,保证输入为数字字符及行末换行符。
对于 80 % 80\% 80% 的数据, 1 ≤ ∣ s ∣ ≤ 5 1 ≤ |s| ≤ 5 1s5,输入只可能包含大、小写英文字母、数字字符及行末换行符。
对于 100 % 100\% 100% 的数据, 1 ≤ ∣ s ∣ ≤ 5 1 ≤ |s| ≤ 5 1s5,输入可能包含大、小写英文字母、数字字符、空格和行末换行符。

1 读入整行输入,包括空白字符,使用getline(cin, string)

AC代码

#include<iostream>
#include<string.h>
using namespace std;

int main()
{
	string input;
	getline(cin, input);
	
	int count = 0;
	
	for(int i = 0; i < input.length(); i++)
	{
		if(input[i] == ' ')
			continue;
		
		count++;
	}
	
	cout << count;
	
	return 0;
} 

P5734【深基6.例6】文字处理软件

题目描述

你需要开发一款文字处理软件。最开始时输入一个字符串作为初始文档。可以认为文档开头是第 0 0 0 个字符。需要支持以下操作:

  • 1 str:后接插入,在文档后面插入字符串 str \texttt{str} str,并输出文档的字符串;
  • 2 a b:截取文档部分,只保留文档中从第 a a a 个字符起 b b b 个字符,并输出文档的字符串;
  • 3 a str:插入片段,在文档中第 a a a 个字符前面插入字符串 str \texttt{str} str,并输出文档的字符串;
  • 4 str:查找子串,查找字符串 str \texttt{str} str 在文档中最先的位置并输出;如果找不到输出 − 1 -1 1

为了简化问题,规定初始的文档和每次操作中的 str \texttt{str} str 都不含有空格或换行。最多会有 q q q 次操作。

输入格式:
第一行输入一个正整数 q q q,表示操作次数。
第二行输入一个字符串 str \texttt{str} str,表示最开始的字符串。
第三行开始,往下 q q q 行,每行表示一个操作,操作如题目描述所示。

·输出格式:
一共输出 q q q 行。
对于每个操作 1 , 2 , 3 1,2,3 1,2,3,根据操作的要求输出一个字符串。
对于操作 4 4 4,根据操作的要求输出一个整数。

样例:
样例输入:

4
ILove
1 Luogu
2 5 5
3 3 guGugu
4 gu

样例输出:

ILoveLuogu
Luogu
LuoguGugugu
3

提示:
数据保证, 1 ≤ q ≤ 100 1 \leq q\le 100 1q100,开始的字符串长度 ≤ 100 \leq 100 100

1 字符串查找、比较等一系列字符串操作函数

一些基本的C++字符串函数及其使用示例的简介:
在C++中,std::string 类提供了许多成员函数来操作字符串。以下是一些常用的成员函数及其简要说明:

  1. length()size():返回字符串中字符的数量。

    string str = "Hello";
    cout << str.length(); // 输出字符串长度,这里是5
    
  2. find():查找子串或字符在字符串中首次出现的位置。

    size_t pos = str.find("lo"); // 查找"lo",返回2
    
  3. rfind():从字符串的末尾开始查找子串或字符首次出现的位置。

    size_t rpos = str.rfind('l'); // 从后往前查找'l',返回3
    
  4. substr():返回字符串的一部分。

    string sub = str.substr(1, 3); // 返回"ell"
    
  5. compare():比较两个字符串。

    string str2 = "Hello";
    if (str.compare(str2) == 0) {} // 比较str和str2  <0 =0>0 
    
  6. append():在字符串末尾添加字符或字符串。

    str.append(" World"); // 在str后面添加" World"
    
  7. insert():在指定位置插入字符或字符串。

    str.insert(5, ","); // 在位置5插入逗号
    
  8. replace():替换字符串中的某一部分。

    str.replace(1, 3, "i"); // 将索引1开始的3个字符替换为"i",结果是"Hio"
    
  9. erase():删除字符串中的一部分。

    str.erase(1, 3); // 删除索引1开始的3个字符
    
  10. clear():清空字符串。

    str.clear(); // 清空字符串
    
  11. empty():检查字符串是否为空。

    if (str.empty()) {} // 检查字符串是否为空
    
  12. c_str():返回一个以null终止的字符数组的指针。

    const char* cstr = str.c_str(); // 获取C风格字符串
    
  13. operator[]:访问字符串中的单个字符。

    char ch = str[1]; // 访问索引1的字符
    
  14. front()back():访问字符串的第一个和最后一个字符。

    char f = str.front(); // 第一个字符
    char b = str.back();  // 最后一个字符
    
  15. push_back():在字符串末尾添加一个字符。

    str.push_back('!'); // 在末尾添加'!'
    
  16. pop_back():删除字符串末尾的一个字符。

    str.pop_back(); // 删除末尾字符
    
  17. += 操作符:连接字符串或字符。

    str += " World"; // 连接字符串
    
  18. + 操作符:生成连接了两个字符串的新字符串。

    string str3 = str + " World"; // 生成新的字符串
    
  19. ==, !=, <, <=, >, >= 操作符:比较两个字符串。

    if (str == str2) {}  // 比较两个字符串是否相等
    

这些函数和操作符使std::string成为处理字符串时非常强大和灵活的工具。

当然,下面是一些基本的C语言字符串函数及其使用示例的简介:

  1. strcpystrncpy:复制字符串。
char src[] = "Hello";
char dest[10];

strcpy(dest, src);
// 使用strncpy需要指定复制的最大长度
strncpy(dest, src, sizeof(dest) - 1);
  1. strcatstrncat:连接两个字符串。
char dest[20] = "Hello, ";
char src[] = "world!";

strcat(dest, src);
// 使用strncat需要指定连接的最大长度
strncat(dest, src, 6);
  1. strcmpstrncmp:比较两个字符串。
char str1[] = "abc";
char str2[] = "abcd";

int result = strcmp(str1, str2);
// 使用strncmp需要指定比较的最大长度
int n_result = strncmp(str1, str2, 3);
  1. strlen:获取字符串的长度。
char str[] = "Hello";
size_t len = strlen(str);
  1. strchrstrrchr:查找字符在字符串中的位置。
char str[] = "Hello, world!";
char *ch = strchr(str, 'o'); // 查找'o'的第一个出现
char *rch = strrchr(str, 'o'); // 查找'o'的最后一个出现
  1. strstr:查找子字符串。
char haystack[] = "Hello, world!";
char needle[] = "world";
char *substr = strstr(haystack, needle);
  1. strspnstrcspn:检索字符串中一部分的长度。
char str1[] = "129th";
char str2[] = "1234567890";
int length = strspn(str1, str2);  // 返回 str1 中开头连续包含在 str2 中的最大字符数

char str3[] = "abcde";
char str4[] = "123";
int length2 = strcspn(str3, str4); // 返回 str3 中开头连续不含 str4 中字符的字符数
  1. strtok:分割字符串。
char str[] = "Hello, world!";
const char delim[] = " ,!";
char *token;

token = strtok(str, delim);
while (token != NULL) {
    printf("%s\n", token);
    token = strtok(NULL, delim);//默认从上次结束的下一个位置开始寻找delim字符
}
  1. strdup:复制字符串。
char src[] = "Hello";
char *dest = strdup(src);
  1. strerror:根据错误号返回描述错误的字符串。
#include <errno.h>
fprintf(stderr, "%s\n", strerror(ENOENT));
  1. strcoll:进行区域设置比较。
char str1[] = "äbc";
char str2[] = "abc";
int result = strcoll(str1, str2);
  1. strpbrk:在字符串中搜索任何一组字符的第一次出现。
char str1[] = "abcde321bc99";
char str2[] = "123";
char *ch = strpbrk(str1, str2);

请注意,strdup是POSIX标准的一部分,而不是C标准库的一部分,因此在某些环境下可能不可用。此外,对于分配了动态内存的strdup,确保在适当的位置使用free释放内存。

2 string.find()函数

string.find(substr)函数进行子串查找,返回最开始找到的位置对应的数字(从0开始)

string.find(substr, position)函数,返回从指定位置position开始查找的结果

找到:position != string::npos
找不到:!(position != string::npos

(input.find(substr) != string::npos) ? cout << input.find(substr) : cout << "-1";

AC代码

#include<iostream>
#include<string.h>
using namespace std;

int main()
{
	int opetime, operation;
	cin >> opetime;
	
	string input, addstring;
	cin >> input;
	
	while(opetime--)
	{
		scanf("%d", &operation);
		
		if(operation == 1)
		{
			getchar();
			
			cin >> addstring;
			
			input += addstring;
			
			cout << input;
		}
		else if(operation == 2)
		{
			getchar();
			
			int begin, end;
			scanf("%d %d", &begin, &end);
			
			input = input.substr(begin, end);
			cout << input; 
//			string copy = input;
//			input = "\0";
//			
//			while(end--)
//			{
//				cout << copy[begin];
//				input += copy[begin];
//				
//				begin++;
//			}
		}
		else if(operation == 3)
		{
			int begin;
			string insert;
			
			scanf("%d", &begin);
			cin >> insert;
			
			input.insert(begin, insert);
			cout << input;
//			string copy = input;
//			input = "\0";
//			
//			for(int i = 0; i < begin; i++)
//			{
//				cout << copy[i];
//				input += copy[i];
//			}
//			
//			cout << insert;
//			input += insert;
//			
//			for(int i = begin; i < copy.length(); i++)
//			{
//				cout << copy[i];
//				input += copy[i];
//			}			
		}
		else if(operation == 4)
		{
			getchar();
			
			string substr;
			
			cin >> substr;
			
			int position;
			
			(input.find(substr) != string::npos) ? cout << input.find(substr) : cout << "-1"; 
			
		}
		
		if(opetime > 0)
			cout << endl;
	}
	
	return 0; 
}

P1308 [NOIP2011 普及组] 统计单词数

题目描述

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

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

输入格式:
2 2 2 行。
1 1 1 行为一个字符串,其中只含字母,表示给定单词;
2 2 2 行为一个字符串,其中只可能包含字母和空格,表示给定的文章。

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

样例:
样例输入:

To
to be or not to be is a question

样例输出:

2 0

样例:
样例输入:

to
Did the Ottoman Empire lose its power at that time

样例输出:

-1

提示:
数据范围
$1\leq $ 第一行单词长度 ≤ 10 \leq10 10
$1\leq $ 文章长度 ≤ 1 0 6 \leq10^6 106
noip2011 普及组第 2 题

1 使用tolower()函数将单个字符转变为小写 使用toupper()函数将单个字符转变为大写

2 size_t表示可能出现的最大值

size_t position

3 要注意开头是空格以及多个连续空格的情况

4 static_cast比(int)进行更加严格的类型转换

只能进行整数类型的转换,而不会将指针转换为整数

C++中的static_cast比C语言中的(int)类型检查更为严格

AC代码

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

int main() {
    string target, line;
    getline(cin, target);
    getline(cin, line);

    // 转换目标单词和整篇文章为小写
    //transform(target.begin(), target.end(), target.begin(), ::tolower);
    //transform(line.begin(), line.end(), line.begin(), ::tolower);
    for(int i = 0; i < target.length(); i++)
	{
		if(target[i] == ' ')
			continue;
			
		target[i] = tolower(target[i]);
	}
	for(int i = 0; i < line.length(); i++)
	{
		if(line[i] == ' ')
			continue;
			
		line[i] = tolower(line[i]);
	}
    

    int count = 0, firstPosition = -1;
    size_t position = 0;

    // 查找目标单词在文章中所有出现的位置
    while ((position = line.find(target, position)) != string::npos) 
	{
        // 检查单词前后是否被空格或文本边界包围
        // 就是判断是否是独立单词
        bool isWordPrefix = (position == 0 || line[position - 1] == ' ');
        size_t wordEnd = position + target.length();
        bool isWordSuffix = (wordEnd == line.length() || line[wordEnd] == ' ');

        if (isWordPrefix && isWordSuffix)//前后都是空格,或者是边界只有一边有空格 
		{
            count++;
            if (firstPosition == -1) 
			{
                firstPosition = static_cast<int>(position);//类型转换
            }
        }
        position += target.length();//不用管连续空格和空格,position的位置只能是正确匹配的单词的后面
    }

    if (count > 0) 
	{
        cout << count << ' ' << firstPosition;
    } 
	else 
	{
        cout << "-1";
    }

    return 0;
}

P1765 手机

题目描述

一般的手机的键盘是这样的:

要按出英文字母就必须要按数字键多下。例如要按出 x \tt x x 就得按 9 9 9 两下,第一下会出 w \tt w w,而第二下会把 w \tt w w 变成 x \tt x x 0 0 0 键按一下会出一个空格。

你的任务是读取若干句只包含英文小写字母和空格的句子,求出要在手机上打出这个句子至少需要按多少下键盘。

输入格式:
一行句子,只包含英文小写字母和空格,且不超过 200 个字符。

输出格式:
一行一个整数,表示按键盘的总次数。

样例
样例输入

i have a dream

样例输出

23

提示:
NOI 导刊 2010 普及(10)

AC代码

#include<string.h>
//#include<bits/stdc++.h> 
#include<iostream>
using namespace std;

int main()
{
	string input;
	getline(cin, input);
	
	int count = 0; 
	
	for(int i = 0; i < input.length(); i++)
	{
		if(input[i] == 'a' || input[i] == 'd' || input[i] == 'g' || input[i] == 'j' ||
		   input[i] == 'm' || input[i] == 'p' || input[i] == 't' || input[i] == 'w' ||
		   input[i] == ' ')
		    count++;
		else if(input[i] == 'b' || input[i] == 'e' || input[i] == 'h' || input[i] == 'k' ||
		        input[i] == 'n' || input[i] == 'q' || input[i] == 'u' || input[i] == 'x' ||
				input[i] == ' ')
			count += 2;
		else if(input[i] == 'c' || input[i] == 'f' || input[i] == 'i' || input[i] == 'l' ||
		        input[i] == 'o' || input[i] == 'r' || input[i] == 'v' || input[i] == 'y')
		    count += 3;
		else if(input[i] == 's' || input[i] == 'z')
			count += 4;
		
	}
	
	cout << count;
	
	return 0;
}

P3741 小果的键盘

题目背景
小果有一个只有两个键的键盘。

题目描述

一天,她打出了一个只有这两个字符的字符串。当这个字符串里含有 VK 这个字符串的时候,小果就特别喜欢这个字符串。所以,她想改变至多一个字符(或者不做任何改变)来最大化这个字符串内 VK 出现的次数。给出原来的字符串,请计算她最多能使这个字符串内出现多少次 VK(只有当 VK 正好相邻时,我们认为出现了 VK。)

输入格式:
第一行给出一个数字 n n n,代表字符串的长度。
第二行给出一个字符串 s s s

输出格式:
第一行输出一个整数代表所求答案。

样例:
样例输入

2
VK

样例输出

1

样例:
样例输入

2
VV

样例输出

1

样例:
样例输入

1
V

样例输出

0

样例:
样例输入

20
VKKKKKKKKKVVVVVVVVVK

样例输出

3

样例:
样例输入

4
KVKV

样例输出

1

提示:
对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 100 1\le n\le 100 1n100

1 对于某种情况只能出现一次、之后就不能计数了,要学会设立flag

2 需要分类的,可以分两次进行判断,将第一次判断过的改为没用的,进行第二次判断

AC代码

#include<iostream>
using namespace std;

int main()
{
	int number, count = 0, flag = 0;
	cin >> number;
	
	char input[number];
	int copy = number;
	
	while(number--)
	{
		cin >> input[copy - number];
	}
	
	//cout << ':' << copy << endl;
	
	for(int i = 0; i < copy; i++)
	{
		if(input[i] == 'V' && input[i + 1] == 'K')
		{
			//flag = 1;
			count++;
			input[i] = input[i + 1] = 'O';
		}
	}
	for(int i = 0; i < copy; i++)
	{
		if((input[i] == 'V' && input[i + 1] == 'V') || (input[i] == 'K' && input[i + 1] == 'K'))
		{
			count++;
			break;
		}
	}
	
	cout << count;
	
	return 0;
}

P1321 单词覆盖还原

题目描述

一个长度为 l l l 的字符串中被反复贴有 boygirl 两单词,后贴上的可能覆盖已贴上的单词(没有被覆盖的用句点表示),最终每个单词至少有一个字符没有被覆盖。问贴有几个 boy 几个 girl

输入格式:
一行被反复贴有 boygirl 两单词的字符串。

输出格式:
两行,两个整数。第一行为 boy 的个数,第二行为 girl 的个数。

样例:
样例输入

......boyogirlyy......girl.......

样例输出

4
2

提示:
数据保证, 3 ≤ l ≤ 255 3\le l\le255 3l255,字符串仅仅包含如下字符: .bgilory \texttt{.bgilory} .bgilory

1 string.replace(begin, length, “”)函数

begin是起点,将之后length长度的字符串替换成引号中的内容
引号为双引号

input.replace(position, length, "x");//length长度换成一个x
image-20240323142118481
input.replace(position, length, "zzz");//length长度换成zzz
image-20240323142315856

2 使用函数时,将main里面的局部变量前置,声明为全局变量,通常是必要操作

AC代码

#include<iostream>
using namespace std;

string input;

int search(string substr)
{
	int position = input.find(substr), count = 0;

	int len = substr.length();
	
	while(position != string::npos)
	{
		count++;
		
		input.replace(position, len, "zzz");
		
		cout << ':' << input << endl; 
		
		position = input.find(substr, position + 1);
	}
	
	return count;
}

int main()
{
	getline(cin, input);
	
	int num_girl = 0, num_boy = 0;
	
	num_girl = search("girl") + search("gir") + search("irl") + search("gi") + search("ir") + search("rl") + search("g") + search("i") + search("r") + search("l");
	
	num_boy = search("boy") + search("bo") + search("oy") + search("b") + search("o") + search("y");
	
	cout << num_boy << endl << num_girl;
	
	return 0;
}

P1553 数字反转(升级版)

题目背景:
以下为原题面,仅供参考:
给定一个数,请将该数各个位上数字反转得到一个新数。

这次与 NOIp2011 普及组第一题不同的是:这个数可以是小数,分数,百分数,整数。整数反转是将所有数位对调;小数反转是把整数部分的数反转,再将小数部分的数反转,不交换整数部分与小数部分;分数反转是把分母的数反转,再把分子的数反转,不交换分子与分母;百分数的分子一定是整数,百分数只改变数字部分。整数新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零;小数新数的末尾不为 0 0 0(除非小数部分除了 0 0 0 没有别的数,那么只保留1个 0 0 0);分数不约分,分子和分母都不是小数(约分滴童鞋抱歉了,不能过哦。输入数据保证分母不为 0 0 0),本次没有负数。

题目描述

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

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

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

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

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

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

输入格式:
一个实数 s s s

输出格式:
一个实数,即 s s s 的反转数

样例
样例输入

5087462

样例输出

2647805

样例
样例输入

600.084

样例输出

6.48

样例
样例输入

700/27

样例输出

7/72

样例
样例输入

8670%

样例输出

768%

提示:
【数据范围】

  • 对于 25 % 25\% 25% 的数据, s s s 是整数,不大于 20 20 20 位;
  • 对于 25 % 25\% 25% 的数据, s s s 是小数,整数部分和小数部分均不大于 10 10 10 位;
  • 对于 25 % 25\% 25% 的数据, s s s 是分数,分子和分母均不大于 10 10 10 位;
  • 对于 25 % 25\% 25% 的数据, s s s 是百分数,分子不大于 19 19 19 位。

【数据保证】

  • 对于整数翻转而言,整数原数和整数新数满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数和原来的数字的最高位数字不应为零。

  • 对于小数翻转而言,其小数点前面部分同上,小数点后面部分的形式,保证满足小数的常见形式,也就是末尾没有多余的 0 0 0(小数部分除了 0 0 0 没有别的数,那么只保留 1 1 1 0 0 0。若反转之后末尾数字出现 0 0 0,请省略多余的 0 0 0

  • 对于分数翻转而言,分数不约分,分子和分母都不是小数。输入的分母不为 0 0 0。与整数翻转相关规定见上。

  • 对于百分数翻转而言,见与整数翻转相关内容。

数据不存在负数。

1 分割字符串可以用string.substr(begin, length)函数

2 数字反转的0可以用while跳过,也可以用flag标记

AC代码

#include<iostream>
using namespace std;

void reverse(string input)
{
	string copy = input;
	int flag = 0;
	
	if(input == "0")
	{
		cout << "0";
		return;
	}
	
	for(int i = 0; i < input.length(); i++)
	{
		copy[input.length() - i - 1] = input[i];
	}
	
	for(int i = 0; i < copy.length(); i++)
	{
		if(flag == 0 && copy[i] == '0') // 如果是0开头
			continue;
		else
		{
			cout << copy[i]; // 已经不是开头了
			flag = 1;
		}
	}
	
	return;
}

int main()
{
	string input;
	cin >> input;
	
	int position1 = input.find(".");
	int position2 = input.find("%");
	int position3 = input.find("/");
	int position = 0;
	
	if(position1 != string::npos || position3 != string::npos)
	{
		if(position1 != string::npos)
			position = position1;
		else
			position = position3;
		
		string sub1 = input.substr(0, position);
		string sub2 = input.substr(position + 1, input.length() - position - 1);
		
		int replace = 0;
		
		while(sub2[replace] == '0' && sub2.length() != 1)//小数部分只有1个0,保留1个0
			replace++;
		sub2 = sub2.substr(replace, sub2.length() - replace);
		
		reverse(sub1);
		cout << input[position];
		reverse(sub2);
	}
	else if(position2 != string::npos)
	{
		string sub;
		sub = input.substr(0, input.length() - 1);
		
		reverse(sub);
		cout << '%';	
	}
	else
		reverse(input);
	
	return 0;
} 

P1603 斯诺登的密码

题目背景
根据斯诺登事件出的一道水题

题目描述

2013 年 X 月 X 日,俄罗斯办理了斯诺登的护照,于是他混迹于一架开往委内瑞拉的飞机。但是,这件事情太不周密了,因为 FBI 的间谍早已获悉他的具体位置——但这不是最重要的——最重要的是如果要去委内瑞拉,那么就要经过古巴,而经过古巴的路在美国的掌控之中。

丧心病狂的奥巴马迫降斯诺登的飞机,搜查时却发现,斯诺登杳无踪迹。但是,在据说是斯诺登的座位上,发现了一张纸条。纸条由纯英文构成:Obama is a two five zero.(以 . 结束输出,只有 6 6 6 个单词+一个句号,句子开头如没有大写亦为合法)这句话虽然有点无厘头,但是警官陈珺骛发现这是一条极其重要的线索。他在斯诺登截获的一台笔记本中找到了一个 C++ 程序,输入这条句子后立马给出了相对应的密码。陈珺鹜高兴得晕了过去,身为警官的你把字条和程序带上了飞机,准备飞往曼哈顿国际机场,但是在飞机上检查的时候发现——程序被粉碎了!飞机抵达华盛顿只剩 5 5 5 分钟,你必须在这 5 5 5 分钟内编写(杜撰)一个程序,免受上司的 10000000000   m o d   10 10000000000 \bmod 10 10000000000mod10 大板。破译密码的步骤如下:

(1)找出句子中所有用英文表示的数字 ( ≤ 20 ) (\leq 20) (20),列举在下:

正规:one two three four five six seven eight nine ten eleven twelve
thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty

非正规:a both another first second third。为避免造成歧义,another 算作 1 1 1 处理。

(2)将这些数字平方后对 100 100 100 取模,如 00 , 05 , 11 , 19 , 86 , 99 00,05,11,19,86,99 00,05,11,19,86,99

(3)把这些两位数按数位排成一行,组成一个新数,如果开头为 0 0 0,就去 0 0 0

(4)找出所有排列方法中最小的一个数,即为密码。

// 数据已经修正 By absi2011 如果还有问题请联系我

输入格式:
一个含有 6 6 6 个单词的句子。

输出格式:
一个整型变量(密码)。如果没有符合要求的数字出现,则输出 0 0 0

样例
样例输入

Black Obama is two five zero .

样例输出

425

1 虽然有一些数据能通过计算表示,但是所有输入都确定,可以直接全局定义数组,打表定义

2 array是常用的名称,尤其是全局范围的数组,尽量不用array

AC代码

#include<iostream>
#include<iomanip>
#include<algorithm>
using namespace std;

string word[27] = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty", "a", "both", "another", "first","second","third"};
int value[27] = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 00, 21, 44, 69, 96, 25, 56, 89, 24, 61, 0, 1, 4, 1, 1, 4, 9};

int main()
{
	string input;
	int position = 0, time = 0, flag = 0;
	int number[6] = {0};

	while(cin >> input)
	{
		//cout << input;
		for(int i = 0; i < 26; i++)
		{
			if(input == word[i])
			{
				number[time++] = value[i];
				//cout << value[i] << endl;
				break;
			}
		}
		
	} 
	
	//cout << '!' << endl;
	
	sort(number, number + time);
	
//	for(int i = 0; i < time; i++)
//	{
//		cout << number[i] << endl;
//	}
	
	for(int i = 0; i < time; i++)
	{
		if(flag == 1)
		{
			printf("%.2d", number[i]);
		}
		else
		{
			if(number[i] != 0)
			{
				cout << number[i];
				flag = 1;
			}
		}		
	}
	
	if(time == 0)
		cout << 0;
	
	return 0;
} 

P1200 [USACO1.1] 你的飞碟在这儿 Your Ride Is Here

题目描述

众所周知,在每一个彗星后都有一只 UFO。这些 UFO 时常来收集地球上的忠诚支持者。不幸的是,他们的飞碟每次出行都只能带上一组支持者。因此,他们要用一种聪明的方案让这些小组提前知道谁会被彗星带走。他们为每个彗星起了一个名字,通过这些名字来决定这个小组是不是被带走的那个特定的小组(你认为是谁给这些彗星取的名字呢?)。关于如何搭配的细节会在下面告诉你;你的任务是写一个程序,通过小组名和彗星名来决定这个小组是否能被那颗彗星后面的 UFO 带走。

小组名和彗星名都以下列方式转换成一个数字:最终的数字就是名字中所有字母的,其中 A \texttt A A 1 1 1 Z \texttt Z Z 26 26 26。例如, USACO \texttt{USACO} USACO 小组就是 21 × 19 × 1 × 3 × 15 = 17955 21 \times 19 \times 1 \times 3 \times 15=17955 21×19×1×3×15=17955。如果小组的数字   m o d   47 \bmod 47 mod47 等于彗星的数字   m o d   47 \bmod 47 mod47,你就得告诉这个小组需要准备好被带走!(记住“ a   m o d   b a \bmod b amodb”是 a a a 除以 b b b 的余数,例如 34   m o d   10 34 \bmod 10 34mod10 等于 4 4 4

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

输入格式:
第1行:一个长度为 1 1 1 6 6 6 的大写字母串,表示彗星的名字。
第2行:一个长度为 1 1 1 6 6 6 的大写字母串,表示队伍的名字。

输出格式:
样例
样例输入

COMETQ
HVNGAT

样例输出

GO

样例
样例输入

ABSTAR
USACO

样例输出

STAY

提示:
题目翻译来自 NOCOW。
USACO Training Section 1.1

AC代码

#include<iostream>
#include<string.h>
using namespace std;

int main()
{
	string plate;
	string group;
	cin >> plate;
	cin >> group;
	//cout << plate << group << endl;
	int num1 = 1, num2 = 1, i = 0;
	
	while(i < plate.length())
	{
		num1 *= (plate[i++] - 'A' + 1);
		//cout << plate[i++] - 'A' << endl; 
		//cout << num1 << endl;
	}
	//cout << num1 << endl;
	num1 %= 47;
	
	i = 0;
	
	while(i < group.length())
	{
		num2 *= (group[i++] - 'A' + 1);
		//cout << num2 << endl;
	}
	//cout << num2 << endl;
	num2 %= 47;
	
	num1 == num2 ? cout << "GO" : cout << "STAY";
	
	return 0;
}

P1597 语句解析

题目描述

一串长度不超过 255 255 255 的 PASCAL 语言代码,只有 a , b , c a,b,c a,b,c 三个变量,而且只有赋值语句,赋值只能是一个一位的数字或一个变量,每条赋值语句的格式是 [变量]:=[变量或一位整数];。未赋值的变量值为 0 0 0 输出 a , b , c a,b,c a,b,c 的值。

输入格式:
一串符合语法的 PASCAL 语言,只有 a , b , c a,b,c a,b,c 三个变量,而且只有赋值语句,赋值只能是一个一位的数字或一个变量,未赋值的变量值为 0 0 0

输出格式:
输出 a , b , c a,b,c a,b,c 最终的值。

样例
样例输入

a:=3;b:=4;c:=5;

样例输出

3 4 5

提示:
输入的 PASCAL 语言长度不超过 255 255 255

AC代码

#include<iostream>
using namespace std;

int main()
{
	string input;
	cin >> input;
	int number[3] = {0};
	int letter = 0;
	
	for(int i = 0; i < input.length(); i++)
	{
		//cout << input[i] << endl;
		if(input[i] == '=')
		{
			if(input[i + 1] >= '0' && input[i + 1] <= '9')
			{
				//cout << input[i + 1] << endl;
				number[input[i - 2] - 'a'] = (input[i + 1] - '0');
			}	
			else
				number[input[i - 2] - 'a'] = number[input[i + 1] - 'a'];
		}
	}
	
	int j = 0;
	
	while(j < 3)
	{
		cout << number[j++];
		
		if(j < 3)
			cout << ' ';
	}
	
	//cout << 'x';
	return 0;
}

P1598 垂直柱状图

题目描述

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

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

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

样例
样例输入

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

样例输出

*
                            *
        *                   *
        *                   *     *   *
        *                   *     *   *
*       *     *             *     *   *
*       *     * *     * *   *     * * *
*       *   * * *     * *   * *   * * * *
*     * * * * * *     * * * * *   * * * *     * *
* * * * * * * * * * * * * * * * * * * * * * * * * *
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 求数组中最大值 使用迭代器max_element(array, array + length_num),不会导致数组元素顺序的改变

函数头文件为

#include<algorithm>

返回的是最大元素位置的指针,变量类型为int *,在max前面加上*,表示指针指向的位置的数值,即数组最大值

int *max = max_element(number, number + 26);
int maxvalue = *max;

2 while中如果末尾没有空格 或者末尾没有换行

使用

if(i < n)
	cout << ' ';

if(i > 0)
	cout << ' ';
	int j = 0;
	while(j < 5)
	{
		cout << '*';
		j++;
		
		if(j < 5)
			cout << ' '; 
	}
	
	cout << "!!!!";
	
    j = 5;
	while(j--)
	{
		cout << '*';
		
		if(j > 0)
			cout << ' '; 
	}
	
	cout << "!!!!";

//输出:* * * * *!!!!* * * * *!!!!

AC代码

#include<algorithm>
#include<string.h>
#include<iostream>
using namespace std;

int main()
{
//	string input;
	int circle = 4;//  4行输入
	
	int number[26] = {0};
	
	while(circle--)
	{
		string input;
		getline(cin, input);
		
		for(int i = 0; i < input.length(); i++)
		{
			if(input[i] - 'A' >= 0 && input[i] - 'A' <= 26)
			{
				number[input[i] - 'A']++;
			}
		}
	}	
	
//	for(int i = 0; i < 26; i++)
//		cout << number[i] << endl;
	
	int *max = max_element(number, number + 26);
	int maxvalue = *max;
	int copy = maxvalue;
	
	for(int i = 0; i < maxvalue; i++)
	{
		for(int j = 0; j < 26; j++)
		{
			if(number[j] - copy == 0 && number[j] != 0)
			{
				number[j]--;
				//maxvalue--;
				
				cout << '*';
			}
			else
				cout << ' ';
			
			if(j < 25)
				cout << ' ';
			
			
		}
		copy--;
		cout << endl;
	}
	
	int i = 26;
	
	while(i--)
	{
		char letter;
		letter = 'A' + 26 - i - 1;
		
		cout << letter;
		
		if(i > 0)
			cout << ' '; 
	}
	
//	int j = 0;
//	while(j < 5)
//	{
//		cout << '*';
//		j++;
//		
//		if(j < 5)
//			cout << ' '; 
//	}
//	
//	cout << "!!!!";
//	
//    j = 5;
//	while(j--)
//	{
//		cout << '*';
//		
//		if(j > 0)
//			cout << ' '; 
//	}
//	
//	cout << "!!!!";
	
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值