【高精】Oliver的成绩

题目描述

给你 O l i v e r Oliver 三科的成绩,分别是 O l i v e r Oliver C h i n e s e Chinese m a t h math E n g l i s h English 的成绩
然后又来了 n n 个人~~(来砸场子的,兄弟们揍他)~~ ,他们也有各自的成绩
现在要你求三科里
O l i v e r Oliver 与这 n n 个人当中 N O . 1 NO.1 的人的成绩

输入

1 1 ~ 3 3 行,你的 C h i n e s e Chinese m a t h math E n g l i s h English 的成绩
4 4 行,来了 n n 个人
5 5 ~ n 3 + 4 n*3+4 行为 n n 个人各自的成绩
注意是
第五行:第1个人Chinese的成绩
第六行:第1个人math的成绩
第七行:第1个人English的成绩
第八行:第2个人Chinese的成绩

输出

O l i v e r Oliver 与这 n n 个人当中 N O . 1 NO.1 的人的成绩
如果 O l i v e r Oliver N O . 1 NO.1 ,就输出 0 0 (都差不多)

样例输入
10 
10
10               
3 
0
80
0
40
0
0
0
0 
100
样例输出
30 70 90

数据范围限制

【数据范围】
对于50%的数据,0<N<1000,0<M<19.
对于100%的数据,0<N<10000,0<M<30.且都为整数。

思路

看了题,原本以为很简单
一看数据,就崩了

高精(悲伤,不多讲)

读入其他人的成绩时,可以进行比较,找到最大的
最后相减输出,完事

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int Others[55],Gap[55];
//Others是别人的成绩,Oliver[0]是成绩的位数
//Gap是Oliver和NO.1的成绩差
int Results[2][4][55];
//Results[i][j][k]
//i=0代表Oliver的成绩,否则为NO.1的成绩
//j=1代表Chinese成绩,2代表math成绩,3代表English
//k就位数,这里是按最低位在最右边(50),k=0时代表成绩的位数
int n,m,t,tot;
string s;
bool flag;
void read(int t)//高精读入
{
	getline(cin,s);
	tot=0;
	while(s[tot]>='0' && '9'>=s[tot])tot++;
	for(int i=0;i<tot;++i)
		Results[0][t][50-(tot-i)+1]=s[i]-'0';
	Results[0][t][0]=tot;
}
/*
Oliver Results read 
Oliver的成绩读入
*/
void readd()//高精读入
{
	memset(Others,0,sizeof(Others));
	getline(cin,s);
	tot=0;
	while(s[tot]>='0' && '9'>=s[tot])tot++;
	for(int i=0;i<tot;++i)
		Others[50-(tot-i)+1]=s[i]-'0';
	Others[0]=tot;
}
/*
Others Results read 
其他人的成绩读入
*/
void Compare(int k)//比较+替换
{
	if(Others[0]>Results[1][k][0] || //如果位数大于别人
	(Others[0]==Results[1][k][0]) &&
	Others[50-(Others[0])+1]>
	Results[1][k][50-Results[1][k][0]+1])//如果位数相同但最大的数大于别人
	{
		for(int i=50;i>=0;--i)
			Results[1][k][i]=Others[i];//全盘替换
		return;
	}
	else if(Others[0]==Results[1][k][0] &&
	Others[50-(Others[0])+1]==
	Results[1][k][50-Results[1][k][0]+1])//如果最高位相同
	{
		int flag=0,i;
		for(i=50-(Others[0])+1;i<=50;++i)//比较每一个位子
			if(Others[i]>Results[1][k][i])//如果别人比NO.1大
			{flag=1;break;}
			else if(Others[i]<Results[1][k][i])//如果别人比NO.1小
					break;
		if(flag)
		{
			for(;i<=50;++i)
				Results[1][k][i]=Others[i];//全盘替换
		}
		return;
	}
}
/*
Others and Rank.1 Compare
其他人与No.1的比较和替换
*/
void Subtraction(int k)
{
	if(Results[0][k][0]>Results[1][k][0] || 
	(Results[0][k][0]==Results[1][k][0] &&
	Results[0][k][50-Results[0][k][0]+1]>
	Results[1][k][50-Results[1][k][0]+1]))return;//判断Oliver是不是比NO.1大
	else
	{
		memset(Gap,0,sizeof(Gap));
		int l=0,r=0;
		for(int i=50;i>0;--i)//高精减
		{
			l=Results[1][k][i]-Results[0][k][i]-r;
			if(l<0)l+=10,r=1;
			else r=0;
			Gap[i]=l;//注意借位
		}
	}
}
/*
Subtraction
减法
*/
void write(int k)//输出
{
	if(Results[0][k][0]>Results[1][k][0] || 
	(Results[0][k][0]==Results[1][k][0] &&
	Results[0][k][50-Results[0][k][0]+1]>
	Results[1][k][50-Results[1][k][0]+1]))printf("0");//判断Oliver是不是比NO.1大
	else
	{
		t=1;
		while(!Gap[t] && t<50)++t;
		while(t<=50)printf("%d",Gap[t++]);
	}
	printf(" ");
} 
int main()
{
	read(1);
	read(2);
	read(3);
	scanf("%d\n",&n);
	for(int i=1;i<=n;++i)
	{
		readd();Compare(1);//读入+比较
		readd();Compare(2);
		readd();Compare(3);
	}
	Subtraction(1);write(1);//高精减和输出
	Subtraction(2);write(2);
	Subtraction(3);write(3);
	return 0;
}

注意

有个漏洞(尽然没卡掉),就是高精减和输出的时候判断 O l i v e r Oliver 是否比 N O . 1 NO.1 大时,只比较了位数和最高位,没有比较其他位数
所以如果WA了,可以在那里加一个 f o r for 语句判断

猜你喜欢

转载自blog.csdn.net/SSL_wujiajie/article/details/88601499