水题找自信——问题 B: 找x、问题 I: 锤子剪刀布、问题 H: 部分A+B、问题 A: 排序、PAT Ranking、问题 C: EXCEL排序

每日刷题(九十一)

问题 B: 找x

题目描述

输入一个数n,然后输入n个数值各不相同,再输入一个值x,输出这个值在这个数组中的下标(从0开始,若不在数组中则输出-1)。

输入

测试数据有多组,输入n(1<=n<=200),接着输入n个数,然后输入x。

输出

对于每组输入,请输出结果。

样例输入

4
1 2 3 4
3

样例输出

2

C++代码:

#include<iostream>
using namespace std;

int main()
{
    
    
	int n;
	int a[201] = {
    
    0};
	int x;
	while(cin >> n)
	{
    
    
		for(int i = 1; i <= n; i++)
		{
    
    
			cin >> a[i];
		}
		x = 0;
		cin >> x;
		int flag = 0;
		for(int i = 1; i <= n; i++)
		{
    
    
			if(x == a[i])
			{
    
    
				cout << i - 1<< endl;
				flag = 1;
				break;
			}
		}
		if(flag != 1)
			cout << "-1" << endl;
	}
	return 0;	
} 

样例运行结果:
在这里插入图片描述
C代码:

#include<cstdio>
const int maxn = 210;
int a[maxn];

int main()
{
    
    
	int n, x;
	while(scanf("%d", &n) != EOF)
	{
    
    
		for(int i = 0; i < n; i++)
		{
    
    
			scanf("%d", &a[i]);
		}
		scanf("%d", &x);
		int k;
		for(k = 0; k < n; k++)
		{
    
    
			if(a[k] == x)
			{
    
    
				printf("%d\n", k);
				break;
			}
		}
		if(k == n)
			printf("-1\n");
	}
	return 0;
}

问题 I: 锤子剪刀布

题目描述

在这里插入图片描述

输入

输入第1行给出正整数N(<=105),即双方交锋的次数。随后N行,每行给出一次交锋的信息,即甲、乙双方同时给出的的手势。C代表“锤子”、J代表“剪刀”、B代表“布”,第1个字母代表甲方,第2个代表乙方,中间有1个空格。

输出

输出第1、2行分别给出甲、乙的胜、平、负次数,数字间以1个空格分隔。第3行给出两个字母,分别代表甲、乙获胜次数最多的手势,中间有1个空格。如果解不唯一,则输出按字母序最小的解。

样例输入

10
C J
J B
C B
B B
B C
C C
C B
J B
B C
J J

样例输出

5 3 2
2 3 5
B B

C++代码:

#include<iostream>
using namespace std;

//在获胜的情况中,按布、锤子、剪刀顺序排列,即BCJ 
int wina[3];
int winb[3];
//甲、乙双方各自分别的胜平负次数情况 
int infoa[3];
int infob[3];

void Guize(char a, char b)
{
    
    
	if(a == b)		//平局的情况 
	{
    
    
		infoa[1] += 1;
		infob[1] += 1;
	}/* 甲赢的情况 */
	else if(a == 'C' && a < b)		//锤子赢剪刀 
	{
    
    
		infoa[0] += 1;
		infob[2] += 1;
		wina[1] += 1; 
	}
	else if(a == 'J' && b == 'B')	//剪刀赢布 
	{
    
    
		infoa[0] += 1;
		infob[2] += 1; 
		wina[2] += 1;
	}
	else if(a == 'B' && b == 'C')	//布赢锤子
	{
    
    
		infoa[0] += 1;
		infob[2] += 1; 
		wina[0] += 1;
	} 
	else		//乙赢甲的情况 
	{
    
    
		if(b == 'B')
		{
    
    
			winb[0] += 1;
		}
		else if(b == 'C')
		{
    
    
			winb[1] += 1;
		}
		else 
		{
    
    
			winb[2] += 1;
		}
		infoa[2] += 1;
		infob[0] += 1;
	}
}

char maxn(int a[])
{
    
    
	int max = a[0];
	int flag = 0;
	for(int i = 1; i < 3; i++)
	{
    
    
		if(max < a[i])
		{
    
    
			max = a[i];
			flag = i;
		}
	}
	if(flag == 0)
		return 'B';
	else if(flag == 1)
		return 'C';
	else
		return 'J';
}

int main()
{
    
    
	int n;
	while(cin >> n)
	{
    
    
		char a[n], b[n];
		for(int i = 0; i < 3; i++)		//初始化 
		{
    
    
			wina[i] = 0;
			winb[i] = 0;
			infoa[i] = 0;
			infob[i] = 0; 
		}
		
		for(int i = 0; i < n; i++)
		{
    
    
			cin >> a[i];
			cin >> b[i];
			Guize(a[i], b[i]);
		}
		for(int i = 0; i < 3; i++)
		{
    
    
			cout << infoa[i] << " ";
		}
		cout << '\n';
		for(int i = 0; i < 3; i++)
		{
    
    
			cout << infob[i] << " ";
		} 
		cout << '\n';
		cout << maxn(wina) << ' ' << maxn(winb) << endl;		
	}
	return 0;
}

样例运行结果如下:
在这里插入图片描述
但是上述代码还是不严谨,因为每行都会多输出一个空格,所以,为了追求完美,我们完善一下上述的C++代码:

#include<iostream>
using namespace std;

//在获胜的情况中,按布、锤子、剪刀顺序排列,即BCJ 
int wina[3];
int winb[3];
//甲、乙双方各自分别的胜平负次数情况 
int infoa[3];
int infob[3];

void Guize(char a, char b)
{
    
    
	if(a == b)		//平局的情况 
	{
    
    
		infoa[1] += 1;
		infob[1] += 1;
	}/* 甲赢的情况 */
	else if(a == 'C' && a < b)		//锤子赢剪刀 
	{
    
    
		infoa[0] += 1;
		infob[2] += 1;
		wina[1] += 1; 
	}
	else if(a == 'J' && b == 'B')	//剪刀赢布 
	{
    
    
		infoa[0] += 1;
		infob[2] += 1; 
		wina[2] += 1;
	}
	else if(a == 'B' && b == 'C')	//布赢锤子
	{
    
    
		infoa[0] += 1;
		infob[2] += 1; 
		wina[0] += 1;
	} 
	else		//乙赢甲的情况 
	{
    
    
		if(b == 'B')
		{
    
    
			winb[0] += 1;
		}
		else if(b == 'C')
		{
    
    
			winb[1] += 1;
		}
		else 
		{
    
    
			winb[2] += 1;
		}
		infoa[2] += 1;
		infob[0] += 1;
	}
}

char maxn(int a[])
{
    
    
	int max = a[0];
	int flag = 0;
	for(int i = 1; i < 3; i++)
	{
    
    
		if(max < a[i])
		{
    
    
			max = a[i];
			flag = i;
		}
	}
	if(flag == 0)
		return 'B';
	else if(flag == 1)
		return 'C';
	else
		return 'J';
}

int main()
{
    
    
	int n;
	while(cin >> n)
	{
    
    
		char a[n], b[n];
		for(int i = 0; i < 3; i++)		//初始化 
		{
    
    
			wina[i] = 0;
			winb[i] = 0;
			infoa[i] = 0;
			infob[i] = 0; 
		}
		
		for(int i = 0; i < n; i++)
		{
    
    
			cin >> a[i];
			cin >> b[i];
			Guize(a[i], b[i]);
		}
		for(int i = 0; i < 3; i++)
		{
    
    
			if(i != 2)
				cout << infoa[i] << " ";
			else
				cout << infoa[i];
		}
		cout << '\n';
		for(int i = 0; i < 3; i++)
		{
    
    
			if(i != 2)
				cout << infob[i] << " ";
			else
				cout << infob[i];
		} 
		cout << '\n';
		cout << maxn(wina) << ' ' << maxn(winb) << endl;		
	}
	return 0;
}

C代码:

#include<cstdio>

int change(char c)
{
    
    
	if(c == 'B')
		return 0;
	if(c == 'C')
		return 1;
	if(c == 'J')
		return 2;
}

int main()
{
    
    
	char mp[3] = {
    
    'B', 'C', 'J'};
	int n;
	scanf("%d", &n);
	//胜平负次数
	int times_A[3] = {
    
    0}, times_B[3] = {
    
    0};
	//获胜的手势
	int hand_A[3] = {
    
    0}, hand_B[3] = {
    
    0};
	char c1, c2;
	int k1, k2;
	for(int i = 0; i < n; i++)
	{
    
    
		getchar();
		scanf("%c %c", &c1, &c2);
		k1 = change(c1);
		k2 = change(c2);
		if((k1 + 1) % 3 == k2)
		{
    
    
			times_A[0]++;
			times_B[2]++;
			hand_A[k1]++;
		}
		else if(k1 == k2)
		{
    
    
			times_A[1]++;
			times_B[1]++;
		}
		else
		{
    
    
			times_A[2]++;
			times_B[0]++;
			hand_B[k2]++; 
		}
	}
	printf("%d %d %d\n", times_A[0], times_A[1], times_A[2]);
	printf("%d %d %d\n", times_B[0], times_B[1], times_B[2]);
	int id1 = 0, id2 = 0;
	for(int i = 0; i < 3; i++)
	{
    
    
		if(hand_A[i] > hand_A[id1])
			id1 = i;
		if(hand_B[i] > hand_B[id2])
			id2 = i;
	} 
	printf("%c %c\n", mp[id1], mp[id2]);
	return 0;
}
	

问题 H: 部分A+B

题目描述

正整数A的“DA(为1位整数)部分”定义为由A中所有DA组成的新整数PA。例如:给定A = 3862767,DA = 6,则A的“6部分”PA是66,因为A中有2个6。
现给定A、DA、B、DB,请编写程序计算PA + PB。

输入

输入在一行中依次给出A、DA、B、DB,中间以空格分隔,其中0 < A, B < 1010

输出

在一行中输出PA + PB的值。

样例输入

3862767 6 13530293 3
3862767 1 13530293 8

样例输出

399
0

典型反面教材代码

#include<iostream>
using namespace std;

int Pdigital(int m, int n)
{
    
    
	int cnt = 0;
	int sum = 0;
	int flag = 0;
	while(m != 0)
	{
    
    
		if(n == m % 10)
		{
    
    
			flag = 1;
			sum += n;
			sum *= 10;
		}
		m /= 10;
	}
	if(flag)
		sum /= 10;
	return sum;
}

int main()
{
    
    
	int a, Da, b, Db;
	while(cin >> a >> Da >> b >> Db)
	{
    
    
		cout << Pdigital(a, Da) + Pdigital(b, Db) << endl;
	}	
	return 0;
}

为什么上面这个答案是错的呢,因为题目中1010已经超出了int的范围,故用long long存放才保险!

正确C++代码:

#include<iostream>
using namespace std;

long long Pdigital(long long m, long long n)
{
    
    
	long long cnt = 0;
	long long sum = 0;
	int flag = 0;
	while(m != 0)
	{
    
    
		if(n == m % 10)
		{
    
    
			flag = 1;
			sum += n;
			sum *= 10;
		}
		m /= 10;
	}
	if(flag)
		sum /= 10;
	return sum;
}

int main()
{
    
    
	long long a, Da, b, Db;
	while(cin >> a >> Da >> b >> Db)
	{
    
    
		cout << Pdigital(a, Da) + Pdigital(b, Db) << endl;
	}	
	return 0;
}

样例运行结果:
在这里插入图片描述
C代码:

#include<cstdio>

int main()
{
    
    
	long long a, b, da, db;
	scanf("%lld%lld%lld%lld", &a, &da, &b, &db);
	long long pa = 0, pb = 0;
	while(a != 0)
	{
    
    
		if(a % 10 == da)
			pa = pa * 10 + da;
		a /= 10;
	}
	while(b != 0)
	{
    
    
		if(b % 10 == db)
			pb = pb * 10 + db;
		b /= 10;
	}
	printf("%lld\n", pa + pb);
	return 0;
}

问题 A: 排序

题目描述

对输入的n个数进行排序并输出。

输入

输入的第一行包括一个整数n(1<=n<=100)。 接下来的一行包括n个整数。

输出

可能有多组测试数据,对于每组数据,将排序后的n个整数输出,每个数后面都有一个空格。
每组测试数据的结果占一行。

样例输入

5
5 4 3 1 2

样例输出

1 2 3 4 5 

C++代码:

#include<iostream>
using namespace std;

void select(int a[], int n)
{
    
    
	for(int i = 0; i < n - 1; i++)
	{
    
    
		int k = i;
		for(int j = i + 1; j < n; j++)
		{
    
    
			if(a[k] > a[j])
			{
    
    
				k = j;
			}
		}
		int t = a[i];
		a[i] = a[k];
		a[k] = t;
	}
}

int main()
{
    
    
	int n;
	while(cin >> n)
	{
    
    
		int a[n] = {
    
    0};
		for(int i = 0; i < n; i++)
		{
    
    
			cin >> a[i];
		}
		select(a, n);
		for(int i = 0; i < n; i++)
		{
    
    
			cout << a[i] << " ";
		}
		cout << endl;
	}
	return 0;
} 

运行结果:
在这里插入图片描述

PAT Ranking

题目描述

Programming Ability Test (PAT) is organized by the College of Computer Science and Technology of Zhejiang University. Each test is supposed to run simultaneously in several places, and the ranklists will be merged immediately after the test. Now it is your job to write a program to correctly merge all the ranklists and generate the final rank.
编程能力测试(PAT)是由浙江大学计算机科学与技术学院组织的。每个测试应该同时在几个地方运行,并且在测试之后,排名列表将立即合并。现在,你的工作是编写一个程序来正确地合并所有的排名,并生成最终的排名。

输入

Each input file contains one test case. For each case, the first line contains a positive number N (≤100), the number of test locations. Then N ranklists follow, each starts with a line containing a positive integer K (≤300), the number of testees, and then K lines containing the registration number (a 13-digit number) and the total score of each testee. All the numbers in a line are separated by a space.
每个输入文件包含一个测试用例。对于每种情况,第一行包含一个正数N(100),即考试位置的数量。然后是N份排名列表,每一份列表都以正整数K(300)、考生人数一行开头,然后是准考证号(13位数字)和考生考试总分在K行开头。一行中的所有数字用空格隔开。

输出

or each test case, first print in one line the total number of testees. Then print the final ranklist in the following format:
registration_number final_rank location_number local_rank
The locations are numbered from 1 to N. The output must be sorted in nondecreasing order of the final ranks. The testees with the same score must have the same rank, and the output must be sorted in nondecreasing order of their registration numbers.
对于每个测试用例,首先在一行中打印测试者的总数。然后以如下格式打印最终排名:
准考证号 最终排名 考场号 考场内排名
位置编号从1到n,输出必须按最终排名的非降序排序。相同分数的考生必须有相同的排名,并且输出必须按他们的准考证号的非降序排序。

输入样例

2
5
1234567890001 95
1234567890005 100
1234567890003 95
1234567890002 77
1234567890004 85
4
1234567890013 65
1234567890011 25
1234567890014 100
1234567890012 85

输出样例

9
1234567890005 1 1 1
1234567890014 1 2 1
1234567890001 3 1 2
1234567890003 3 1 2
1234567890004 5 1 4
1234567890012 5 2 2
1234567890002 7 1 5
1234567890013 8 2 3
1234567890011 9 2 4

C++代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

/*             定义结构体             */ 
struct Student{
    
    				
	char id[15];			//准考证号 
	int score;				//分数 
	int location_number;	//考场号	
	int local_rank;			//考场内排名 
}stu[30010];

bool cmp(Student a, Student b)
{
    
    
	if(a.score != b.score)
	{
    
    
		return a.score > b.score;
	}
	else 
	{
    
    
		return strcmp(a.id, b.id) < 0;
	}
}

int main()
{
    
    
	int n, k, num = 0;
	scanf("%d", &n);				//总考场数n 
	for(int i = 1; i <= n; i++)
	{
    
    
		scanf("%d", &k);			//第x考场内人数 
		for(int j = 0; j < k; j++)
		{
    
    
			scanf("%s %d", stu[num].id, &stu[num].score);
			stu[num].location_number = i;
			num++;					//考生总人数num 
		}
		
		sort(stu + num - k, stu + num, cmp);		//将该考场内的考生排序 
		stu[num - k].local_rank = 1;				//开始封名次 
		for(int j = num - k + 1; j < num; j++)
		{
    
    
			if(stu[j].score == stu[j - 1].score)
			{
    
    
				stu[j].local_rank = stu[j - 1].local_rank;
			}
			else
			{
    
    
				stu[j].local_rank = j + 1 - (num - k);		 
			}
		}
	}
	printf("%d\n", num);
	sort(stu, stu + num, cmp);
	int r = 1;
	for(int i = 0; i < num; i++)
	{
    
    
		if(i > 0 && stu[i].score != stu[i - 1].score)
		{
    
    
			r = i + 1; 
		}
		printf("%s ", stu[i].id);
		printf("%d %d %d\n", r, stu[i].location_number, stu[i].local_rank);
	}
	return 0;
}

样例运行结果:
在这里插入图片描述

问题 C: EXCEL排序

题目描述

Excel可以对一组纪录按任意指定列排序。现请你编写程序实现类似功能。
对每个测试用例,首先输出1行“Case i:”,其中 i 是测试用例的编号(从1开始)。随后在 N 行中输出按要求排序后的结果,即:当 C=1 时,按学号递增排序;当 C=2时,按姓名的非递减字典序排序;当 C=3 时,按成绩的非递减排序。当若干学生具有相同姓名或者相同成绩时,则按他们的学号递增排序。

输入

测试输入包含若干测试用例。每个测试用例的第1行包含两个整数 N (N<=100000) 和 C,其中 N 是纪录的条数,C 是指定排序的列号。以下有N行,每行包含一条学生纪录。每条学生纪录由学号(6位数字,同组测试中没有重复的学号)、姓名(不超过8位且不包含空格的字符串)、成绩(闭区间[0, 100]内的整数)组成,每个项目间用1个空格隔开。当读到 N=0 时,全部输入结束,相应的结果不要输出。

输出

对每个测试用例,首先输出1行“Case i:”,其中 i 是测试用例的编号(从1开始)。随后在 N 行中输出按要求排序后的结果,即:当 C=1 时,按学号递增排序;当 C=2时,按姓名的非递减字典序排序;当 C=3 时,按成绩的非递减排序。当若干学生具有相同姓名或者相同成绩时,则按他们的学号递增排序。

样例输入

4 1
000001 Zhao 75
000004 Qian 88
000003 Li 64
000002 Sun 90
4 2
000005 Zhao 95
000011 Zhao 75
000007 Qian 68
000006 Sun 85
4 3
000002 Qian 88
000015 Li 95
000012 Zhao 70
000009 Sun 95
0 3

样例输出

Case 1:
000001 Zhao 75
000002 Sun 90
000003 Li 64
000004 Qian 88
Case 2:
000007 Qian 68
000006 Sun 85
000005 Zhao 95
000011 Zhao 75
Case 3:
000012 Zhao 70
000002 Qian 88
000009 Sun 95
000015 Li 95

C++代码:

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

struct Student{
    
    
	char id[7]; 
	char name[10];
	int score;
}a[100001];

bool cmp1(Student a, Student b)
{
    
    
	return strcmp(a.id, b.id) < 0;
}

bool cmp2(Student a, Student b)
{
    
    
	return strcmp(a.name, b.name) < 0;
}

bool cmp3(Student a, Student b)
{
    
    
	if(a.score != b.score)
	{
    
    
		return a.score < b.score;
	}
	else if(a.score == b.score || a.name == b.name)
	{
    
    
		return a.id < b.id;
	}
}

int main()
{
    
    
	int n;
	while(cin >> n)
	{
    
    
		int choose;
		cin >> choose;
		if(n == 0)
			break;
		for(int i = 0; i < n; i++)
		{
    
    
			cin >> a[i].id >> a[i].name >> a[i].score;
		}
		switch(choose)
		{
    
    
			case 1:
				sort(a, a + n, cmp1);
				cout << "Case 1:" << endl;
				break;
			case 2:
				sort(a, a + n, cmp2);
				cout << "Case 2:" << endl;
				break;
			case 3:
				sort(a, a + n, cmp3);
				cout << "Case 3:" << endl;
				break;	
		}
		for(int i = 0; i < n; i++)
		{
    
    
			cout << a[i].id << " " << a[i].name << " " << a[i].score << endl; 
		}
	}
	return 0;
}

样例运行结果:
在这里插入图片描述
上面这个代码不严谨,虽然样例运行结果符合题意。

不严谨在于题目说了,当若干学生具有相同姓名或者相同成绩时,则按他们的学号递增排序。

所以函数cmp2需要完善一下,其实还有其他欠考虑的地方,等你们发现

完善后的C++代码如下:

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

struct Student{
    
    
	char id[10]; 
	char name[10];
	int score;
}a[100010];

bool cmp1(Student a, Student b)
{
    
    
	return strcmp(a.id, b.id) < 0;
}

bool cmp2(Student a, Student b)
{
    
    
	if(strcmp(a.name, b.name))
		return strcmp(a.name, b.name) < 0;
	else
		return strcmp(a.id, b.id) < 0;
}

bool cmp3(Student a, Student b)
{
    
    
	if(a.score != b.score)
	{
    
    
		return a.score < b.score;
	}
	else 
	{
    
    
		return strcmp(a.id, b.id) < 0;
	}
}

int main()
{
    
    
	int n;
	int choose;
	int cnt = 0;
	while(cin >> n >> choose)
	{
    
    
		if(n == 0)
			break;
		for(int i = 0; i < n; i++)
		{
    
    
			cin >> a[i].id >> a[i].name >> a[i].score;
		}
		switch(choose)
		{
    
    
			case 1:
				sort(a, a + n, cmp1);
				break;
			case 2:
				sort(a, a + n, cmp2);
				break;
			case 3:
				sort(a, a + n, cmp3);
				break;	
		}
		cout << "Case " << ++cnt << ":" << endl; 
		for(int i = 0; i < n; i++)
		{
    
    
			cout << a[i].id << " " << a[i].name << " " << a[i].score << endl; 
		}
	}
	return 0;
}

另一个版本的C++代码:

#include <stdio.h>
#include <string.h>
#include <algorithm> 
using namespace std;
struct student{
    
    
	char num[10];
	char name[10];
	int score;
}stu[100010];
bool cmp1(student a,student b){
    
    
	return strcmp(a.num,b.num )<0;
}
bool cmp2(student a,student b){
    
    
	if(strcmp(a.name ,b.name ))	return strcmp(a.name ,b.name )<0;
	else return  strcmp(a.num,b.num )<0;
}
bool cmp3(student a,student b){
    
    
	if(a.score !=b.score )	return a.score <b.score ;
	else	return  strcmp(a.num,b.num )<0;
}
int main(){
    
    
	int m,n,count=0;
	while(scanf("%d %d",&m,&n)!=EOF){
    
    
		if(m==0) break;
		int i;
		for(i=0;i<m;i++){
    
    
			scanf("%s %s %d",&stu[i].num ,&stu[i].name ,&stu[i].score );
		}
		switch(n){
    
    
			case 1:sort(stu,stu+m,cmp1);break;
			case 2:sort(stu,stu+m,cmp2);break;
			case 3:sort(stu,stu+m,cmp3);break;
		}
		printf("Case %d:\n",++count);
		for(i=0;i<m;i++){
    
    
			printf("%s %s %d\n",stu[i].num ,stu[i].name ,stu[i].score );
		}
	}
	return 0;
}

之后我会持续更新,如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持!

猜你喜欢

转载自blog.csdn.net/qq_44631615/article/details/113360054