浙大pat | 浙大pat乙级 1005~1008

 1005

德才论 (25)

2356

9692

24%

宋代史学家司马光在《资治通鉴》中有一段著名的德才论是故才德全尽谓之圣人,才德兼亡谓之愚人,德胜才谓之君子,才胜德谓之

小人。凡取人之术,苟不得圣人,君子而与之,与其得小人,不若得愚人。



现给出一批考生的德才分数,请根据司马光的理论给出录取排名。



输入描述:

输入第1行给出3个正整数,分别为:N<=105),即考生总数;L>=60),为录取最低分数线,即德分和才分均不低于L的考生才有资格

被考虑录取;H<100),为优先录取线——德分和才分均不低于此线的被定义为才德全尽,此类考生按德才总分从高到低排序;才分不到

但德分到线的一类考生属于德胜才,也按总分排序,但排在第一类考生之后;德才分均低于H,但是德分不低于才分的考生属于才德兼

但尚有德胜才者,按总分排序,但排在第二类考生之后;其他达到最低线L的考生也按总分排序,但排在第三类考生之后。


随后N行,每行给出一位考生的信息,包括:准考证号、德分、才分,其中准考证号为8位整数,德才分为区间[0, 100]内的整数。数字间以空格分隔。




输出描述:

输出第1行首先给出达到最低分数线的考生人数M,随后M行,每行按照输入格式输出一位考生的信息,考生按输入中说明的规则从高到低排序。当某类考生中有多人

总分相同时,按其德分降序排列;若德分也并列,则按准考证号的升序输出。



输入例子:

14 60 80

10000001 64 90

10000002 90 60

10000011 85 80

10000003 85 80

10000004 80 85

10000005 82 77

10000006 83 76

10000007 90 78

10000008 75 79

10000009 59 90

10000010 88 45

10000012 80 100

10000013 90 99

10000014 66 60



输出例子:

12

10000013 90 99

10000012 80 100

10000003 85 80

10000011 85 80

10000004 80 85

10000007 90 78

10000006 83 76

10000005 82 77

10000002 90 60

10000014 66 60

10000008 75 79

10000001 64 90

浙大pat的题目真的是麻烦,没错,非常的麻烦,难到不难

这一题只需要使用vector线性表,然后定义一个数据结构cell,把符合要求的学生都放入vector里面,这一题的关键就在于排序函数,重写cmp排序函数,详细的定义两个不同的学生之间的排序的先后关系,然后使用sort函数就能够直接得到结果

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

struct cell {
	int d, c;
	string num;
	cell(string num1,int d1,int c1): d(d1),c(c1),num(num1) {}
};
int H;
bool cmp(cell & a, cell &b)
{
	int counta,countb;
	if (a.d >= H)
	{
		if (a.c >= H) counta = 3;
		else
		{
			counta = 2;
		}
	}
	else
	{
		if (a.d >= a.c) counta = 1;
		else counta = 0;
	}
	if (b.d >= H)
	{
		if (b.c >= H) countb = 3;
		else
		{
			countb = 2;
		}
	}
	else
	{
		if (b.d >= b.c) countb = 1;
		else countb = 0;
	}
	if (counta == countb)
	{
		if (a.c + a.d == b.c + b.d)
		{
			if (a.d == b.d)
			{
				return a.num.compare(b.num) < 0;
			}
			else
			{
				return a.d > b.d;
			}
		}
		else
		{
			return a.c + a.d > b.c + b.d;
		}
	}
	else
	{
		return counta > countb;
	}
}
int main()
{
	int N, L,peoples=0;
	cin >> N >> L >> H;
	vector<cell> theR;
	string num; int d, c;
	for (int i = 0; i < N; i++)
	{
		cin >> num >> d >> c;
		if (d>=L&&c>=L)
		{
			peoples++;
			theR.push_back(cell(num,d, c));
		}
	}
	sort(theR.begin(), theR.end(), cmp);
	cout << peoples << endl;
	for (auto u : theR)
		cout << u.num << " " << u.d << " " << u.c << endl;

	cin.get();
	cin.get();
return 0;
}

 1006

1016. 部分A+B (15)

3259

7159

45%

题目描述

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



输入描述:

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




输出描述:

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



输入例子:

3862767 6 13530293 3



输出例子:

399

这一题还是挺简单的,取A和B的每一位,统计之后然后相加,就能够得到最终的结果,不过我的时间不是很短,这里需要注意的是,假如把A和B转换成sting来进行处理和统计,然后在自己写一个string大数相加的函数,能够节省很大一部分的时间!

#include<iostream>
using namespace std;

long long getD(long long num,int mark)
{
	long long result = 0;
	int tmp;
	while (num != 0)
	{
		tmp = num % 10;
		if (tmp == mark)
		{
			result = result * 10 + tmp;
		}
		num /= 10;
	}
	return result;
}
int main()
{
	long long A, B;
	int Da, Db;
	cin >> A >> Da >> B >> Db;
	long long At, Bt;
	At = getD(A, Da);
	Bt = getD(B, Db);
	cout << At+Bt;
return 0;
}

 1007

A除以B (20)

2970

7028

42%

题目描述

本题要求计算A/B,其中A是不超过1000位的正整数,B1位正整数。你需要输出商数Q和余数R,使得A = B * Q + R成立。



输入描述:

输入在1行中依次给出AB,中间以1空格分隔。




输出描述:

1行中依次输出QR,中间以1空格分隔。



输入例子:

123456789050987654321 7



输出例子:

17636684150141093474 3

这就是一个大数除法的题目,使用大数除法的方法去解决就好了,这一题唯一需要注意的就是当把char转换成int的时候和把int转换成char的时候一个是减去’0’一个是加上’0’,一定要记住!

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

int main()
{
	string a;
	string result = "";
	int b;
	cin >> a >> b;
	int tmp = 0; int l;
	int i;
	for (i = 0; i < a.size(); i++)
	{
		l = tmp * 10 + a[i] - '0';
		result.push_back(l/b+'0');
		tmp = l%b;
	}
	for (i = 0; result[i] == '0'; i++);
	cout << result.substr(i, result.size() - i)<<" "<<tmp;

return 0;
}

 1008

锤子剪刀布 (20)

2421

7118

34%

题目描述

大家应该都会玩锤子剪刀布的游戏:

现给出两人的交锋记录,请统计双方的胜、平、负次数,并且给出双方分别出什么手势的胜算最大。



输入描述:

输入第1行给出正整数N<=105),即双方交锋的次数。随后N行,每行给出一次交锋的信息,即甲、乙双方同时给出的的手势。C代表锤子J代表剪刀B

,第1个字母代表甲方,第2个代表乙方,中间有1个空格。




输出描述:

输出第12行分别给出甲、乙的胜、平、负次数,数字间以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


#include<iostream>
#include<map>
using namespace std;

int main()
{
	int whoWin[2][3] = { 0 };
	map<char, int> comP;
	map<char, int> aWin;
	map<char, int> bWin;
	comP['C'] = 0;
	comP['J'] = 1;
	comP['B'] = 2;
	int N;
	cin >> N;
	char a, b;
	for (int i = 0; i < N; i++)
	{
		cin >> a >> b;
		if(a==b)
		{ 
			whoWin[0][1]++;
			whoWin[1][1]++;
		}
		else if((comP[a]+1)%3==comP[b])
		{
			whoWin[0][0]++;
			whoWin[1][2]++;
			aWin[a]++;
		}
		else
		{
			whoWin[0][2]++;
			whoWin[1][0]++;
			bWin[b]++;
		}

	}
	char aWinW='B', bWinW='B';
	int aH=0, bH=0;
	map<char, int> ::iterator it;
	for (it = aWin.begin(); it != aWin.end(); it++)
	{
		if ((*it).second > aH)
		{
			aH = (*it).second;
			aWinW = (*it).first;
		}
	}
	for (it = bWin.begin(); it != bWin.end(); it++)
	{
		if ((*it).second > bH)
		{
			bH = (*it).second;
			bWinW = (*it).first;
		}
	}
	cout << whoWin[0][0] << " " << whoWin[0][1] << " " << whoWin[0][2]<<endl;
	cout << whoWin[1][0] << " " << whoWin[1][1] << " " << whoWin[1][2]<<endl;
	cout << aWinW << " " << bWinW;
return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值