第七周测试

7546 统计数字字符个数 http://noi.openjudge.cn/ch0107/01/
* 7804 找第一个只出现一次的字符 http://noi.openjudge.cn/ch0107/02/
7599 石头剪子布 http://noi.openjudge.cn/ch0107/04/
* 7600 最长最短单词 http://noi.openjudge.cn/ch0107/25/
* 8173 密码翻译 http://noi.openjudge.cn/ch0107/09/

01:统计数字字符个数 http://noi.openjudge.cn/ch0107/01/

描述

输入一行字符,统计出其中数字字符的个数。

输入

一行字符串,总长度不超过255。

输出

输出为1行,输出字符串里面数字字符的个数。

样例输入

Peking University is set up at 1898.

样例输出

4

 【注】循环那里还可以这样写。

int len = strlen(a);

for(int i =0; i < len; ++i)

#include<iostream>
#define MAXN 265
char a[MAXN];
using namespace std;
int main()
{
	gets(a);//cin和scanf读入空格就终止了,不能用这两个读入 
	int count = 0;
	for(int i = 0; a[i]; ++i)//a[i]==0即a[i]=='\0'时终止循环 
	{
		if(a[i] >= '0' && a[i] <= '9')
			++ count;
	}
	cout << count << endl;
	return 0;
} 

02:找第一个只出现一次的字符 http://noi.openjudge.cn/ch0107/02/

描述

给定一个只包含小写字母的字符串,请你找到第一个仅出现一次的字符。如果没有,输出no。

输入

一个字符串,长度小于100000。

输出

输出第一个仅出现一次的字符,若没有则输出no。

样例输入

abcabd

样例输出

c

【思路】找第一个仅仅出现一次的字符,重要的是对字符数组中出现的字符进行计数。计数可以再开一个数组,专门计算次数。也可以变量字符数组的每一个数,依次进行计数。

#include<iostream>
#define MAXN 100010
char a[MAXN];
int c[30];
using namespace std;
int main()
{
	gets(a);
 	for(int i = 0; a[i]; ++i)
 	{
 		++ c[a[i] - 'a']; //对a[i]中每个字符出现的次数进行计数 
	}
	for(int i = 0; a[i]; ++i)
	{
		if(c[a[i] - 'a'] == 1)
		{
			cout << a[i] << endl;
			return 0;
		}
	}
	cout << "no" << endl;
	return 0;
} 
#include<iostream>
#include<cstdlib>//exit
#define MAXN 100010
char a[MAXN];
using namespace std;
int main()
{
	gets(a);
	int k;
	for(int i = 0; a[i]; ++i)
	{
		k = 0;
		for(int j = 0; a[j]; ++j)
		{
			if(a[i] == a[j]) ++k;
		}
		if(k == 1)
		{
			cout << a[i] << endl;
			exit(0);
		}
	} 
	cout << "no" << endl;
	return 0;
}

04:石头剪子布 http://noi.openjudge.cn/ch0107/04/

描述

石头剪子布,是一种猜拳游戏。起源于中国,然后传到日本、朝鲜等地,随着亚欧贸易的不断发展它传到了欧洲,到了近现代逐渐风靡世界。简单明了的规则,使得石头剪子布没有任何规则漏洞可钻,单次玩法比拼运气,多回合玩法比拼心理博弈,使得石头剪子布这个古老的游戏同时用于“意外”与“技术”两种特性,深受世界人民喜爱。 

游戏规则:石头打剪刀,布包石头,剪刀剪布。 

现在,需要你写一个程序来判断石头剪子布游戏的结果。

输入

输入包括N+1行:
第一行是一个整数N,表示一共进行了N次游戏。1 <= N <= 100。
接下来N行的每一行包括两个字符串,表示游戏参与者Player1,Player2的选择(石头、剪子或者是布):
S1 S2
字符串之间以空格隔开S1,S2只可能取值在{"Rock", "Scissors", "Paper"}(大小写敏感)中。

输出

输出包括N行,每一行对应一个胜利者(Player1或者Player2),或者游戏出现平局,则输出Tie。

样例输入

3
Rock Scissors
Paper Paper
Rock Paper

样例输出

Player1
Tie
Player2

提示

Rock是石头,Scissors是剪刀,Paper是布。

【思路1】先固定一种情况,如固定Player1的情况,然后再列举Player2的可能性。

只用写首字母要简单很多,这里可以改进一下下。

#include<iostream>
#include<cstring>
using namespace std;
char s1[10];
char s2[10];
int main()
{
	int n;
	cin >> n;
	while (n--)
	{
		cin >> s1 >> s2;
		if(strcmp(s1, "Rock") == 0)
		{
			if(strcmp(s2, "Rock") == 0)
				cout << "Tie" << endl;
			else if(strcmp(s2, "Scissors") == 0)
				cout << "Player1" << endl;
			else 
				cout << "Player2" << endl;
		}
		else if(strcmp(s1, "Scissors") == 0)
		{
			if(strcmp(s2, "Scissors") == 0)
				cout << "Tie" << endl;
			else if(strcmp(s2, "Paper") == 0)
				cout << "Player1" << endl;
			else 
				cout << "Player2" << endl;
		}
		else if(strcmp(s1, "Paper") == 0)
		{
			if(strcmp(s2, "Paper") == 0)
				cout << "Tie" << endl;
			else if(strcmp(s2, "Rock") == 0)
				cout << "Player1" << endl;
			else 
				cout << "Player2" << endl;
		}
	}
	return 0;	
} 

【思路2】先列举Player1赢的可能选择,再列举相等的选择,剩余的就是输。

#include<iostream>
char s1[10];
char s2[10];
using namespace std;
int main()
{
	int n;
	cin >> n;
	while(n--)
	{
		cin >> s1 >> s2;
		if((s1[0] == 'R' && s2[0] == 'S') || (s1[0] == 'P' && s2[0] == 'R') || (s1[0] == 'S' && s2[0] == 'P'))
			cout << "Player1" << endl;
		else if(s1[0] == s2[0])
			cout << "Tie" << endl;
		else
			cout << "Player2" << endl;
	}
	return 0;
}

25:最长最短单词 http://noi.openjudge.cn/ch0107/25/

描述

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

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

输入

一行句子。

输出

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

样例输入

I am studying Programming language C in Peking University

样例输出

Programming
I

提示

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

【思路】这个题需要计算每一个单词的长度,然后再更新最大最小长度即可。

计算每一个单词的长度,每个单词是以空格或者逗号分隔的,所以分隔条件是看看a[i]是否是空格或者逗号;分隔好单词后就可以遍历来计数了。

本题也可以单独设置一个数组来记录每个单词的长度,但是很浪费空间和时间,建议还是不要用。

#include<iostream>
#include<cstring>
char a[25000];// 数组要足够大 
using namespace std;
int main()
{
	gets(a);
	int minn = 110, maxn = 0, c, d, e, q = 0, b = 0;
	int l = strlen(a);
	a[l] = ' ';//必须加这一句,否则会运行错误,runtime Error 
	for(int i = 0; i <= l; ++i)
	{
		if(a[i] != ' ' && a[i] != ',')
		{
		 	++ b;
		}
		else if(b > 0)
		{
			if(b > maxn) 
			{
		 		maxn = b;
		 		c = i - b;
			}
		 	if(b < minn) 
		 	{
		 		minn = b;
		 		d = i - b;
			}
			b = 0;//记得要清零 
		}
	
	}	 
	for(int i = c; i <= c + maxn - 1; ++i)
		cout << a[i];
	cout << endl;
	for(int i = d; i <= d + minn - 1; ++i)
		cout << a[i];
	return 0;	
}

为什么会运行错误呢?

c和d没有定义初始值,当后面c和d的值如果不更新的话,即 没有运行后面的else if语句(没有单词或者只有一个单词都不会运行),此时系统会自动给c和d随机分配一个值,后面的输出a[i]时可能会导致数组越界。

改进:

以后写代码的时候,尽量都对变量赋一个初始值。

#include<iostream>
#include<cstring>
char a[25000];// 数组要足够大 
using namespace std;
int main()
{
	gets(a);
	int minn = 110, maxn = 0, c = 0, d = 0, q = 0, b = 0;
	int l = strlen(a);
	a[l] = ' ';//必须加这一句,否则会运行错误,runtime Error,因为c和d没有定义初始值,系统会随机定义一个值给她,导致后面输出的代码数组越界。 
	for(int i = 0; i <= l; ++i)//要比较到最后一个单词,如果i!=l无法比较到最后一个单词,比如一个单词的情况 
	{
		if(a[i] != ' ' && a[i] != ',')
		{
		 	++ b;
		}
		else if(b > 0)//当a[i]=‘ ’或者a[i] = ',' 
		{
			if(b > maxn) 
			{
		 		maxn = b;
		 		c = i - b;
			}
		 	if(b < minn) 
		 	{
		 		minn = b;
		 		d = i - b;
			}
			b = 0;//记得要清零 
		}
	
	}	 
	for(int i = c; i <= c + maxn - 1; ++i)
		cout << a[i];
	cout << endl;
	for(int i = d; i <= d + minn - 1; ++i)
		cout << a[i];
	return 0;	
}

如果不使用a[l] = ' ',则要考虑最后一个单词是否计算进去的问题,当a[l]=‘\0’时,也要记得更新最大值与最小值

#include<iostream>
#include<cstring>
char a[25000];// 数组要足够大 
using namespace std;
int main()
{
	gets(a);
	int minn = 110, maxn = 0, c = 0, d = 0, q = 0, b = 0;
	int l = strlen(a);
	//a[l] = ' ';//必须加这一句,否则会运行错误,runtime Error,因为c和d没有定义初始值,系统会随机定义一个值给她,导致后面输出的代码数组越界。 
	for(int i = 0; i <= l; ++i)//要比较到最后一个单词,如果i!=l无法比较到最后一个单词,比如一个单词的情况 
	{
		if(a[i] != ' ' && a[i] != ',' && a[i] != '\0')
		{
		 	++ b;
		}
		else if(b > 0)//当a[i]=‘ ’或者a[i] = ', 
		{
			if(b > maxn) 
			{
		 		maxn = b;
		 		c = i - b;
			}
		 	if(b < minn) 
		 	{
		 		minn = b;
		 		d = i - b;
			}
			b = 0;//记得要清零 
		}
	
	}	 
	for(int i = c; i <= c + maxn - 1; ++i)
		cout << a[i];
	cout << endl;
	for(int i = d; i <= d + minn - 1; ++i)
		cout << a[i];
	return 0;	
}

09:密码翻译 http://noi.openjudge.cn/ch0107/09/

描述

在情报传递过程中,为了防止情报被截获,往往需要对情报用一定的方式加密,简单的加密算法虽然不足以完全避免情报被破译,但仍然能防止情报被轻易的识别。我们给出一种最简的的加密方法,对给定的一个字符串,把其中从a-y,A-Y的字母用其后继字母替代,把z和Z用a和A替代,其他非字母字符不变,则可得到一个简单的加密字符串。

输入

输入一行,包含一个字符串,长度小于80个字符。

输出

输出每行字符串的加密字符串。

样例输入

Hello! How are you!

样例输出

Ifmmp! Ipx bsf zpv!

 【思路】本题比较简单,主要注意“把z和Z用a和A替代,其他非字母字符不变”这里,用if语句判断即可。

#include<iostream>
char s[90];
using namespace std;
int main()
{
	gets(s);
	for(int i = 0; s[i]; ++i)
	{
		if((s[i] >= 'a' && s[i] <= 'y') || (s[i] >= 'A' && s[i] <= 'Y'))
		{
			s[i] = s[i] +1;
		}
		else if(s[i] == 'z') s[i] = 'a';
		else if(s[i] == 'Z') s[i] = 'A';
		else s[i] = s[i];
	}
	for(int i = 0; s[i]; ++i) 
		cout << s[i];
	return 0;
} 

输出时还可以直接输出,不用遍历也可以。

#include<iostream>
char s[90];
using namespace std;
int main()
{
	gets(s);
	for(int i = 0; s[i]; ++i)
	{
		if((s[i] >= 'a' && s[i] <= 'y') || (s[i] >= 'A' && s[i] <= 'Y'))
		{
			s[i] = s[i] +1;
		}
		else if(s[i] == 'z') s[i] = 'a';
		else if(s[i] == 'Z') s[i] = 'A';
	}
	cout << s;
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/yanyanwenmeng/article/details/81111233