2018SCUACM Training1 贪心

本文介绍了一系列使用贪心算法解决的实际问题,包括字符串完美度计算、构造特定子序列、购买最优烧烤组合、讲座座位安排、自行车运输策略、卡片覆盖游戏、机器人吸尘器噪声优化及田忌赛马问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

点击打开 2018SCUACM Training1 贪心

A - LiAlH4的字符串

追求完美的LiAlH4定义了一个叫字符串完美度的东西。字符串的完美度等于它里面所有字母的完美度之和。每个字母的完美度可以由他自己来分配,不同字母的完美度不同,分别对应一个1-26之间的整数。
LiAlH4不在乎字母大小写。(也就是说字母F和f)的完美度相同。现在给你一个字符串,LiAlH4希望你帮他计算出它的最大可能的完美度。例如:dad,你可以将26分配给d,25分配给a,这样整个字符串完美度为77。

Input

输入一个字符串S(S的长度 <= 10000),S中没有除字母外的其他字符。

Output

由你将1-26分配给不同的字母,使得字符串S的完美度最大,输出这个完美度。

Sample Input
dad
Sample Output
77

这题本身不算特别难,如果知道一个神奇的东西叫做排序不等式的话(顺序和≥乱序和≥反序和)那这题就非常简单了(我记得高中讲过这个不等式)。基于贪心的思想,我们很容易想到,出现次数越多的字母,它对应的完美度尽可能的大,就容易使得总体的完美度尽可能的大。所以,我们需要统计字符串中每个字母的出现次数(这时'A'和'a'看成是相同的),然后对出现次数进行排序,让出现次数最多的字母完美度为26,其次为25,以此类推即可。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
int toNum(char ch)
{
	if('a' <= ch && ch <= 'z')
		return ch-'a';
	if('A' <= ch && ch <= 'Z')
		return ch-'A';
	return 0;
}
int main()
{
	int cnt[30];
	int i,l,ans;
	char s[10005];
	while(scanf("%s",s) != EOF)
	{
		memset(cnt,0,sizeof(cnt));
		l = strlen(s);
		for(i = 0; i < l; i++)
		{
			cnt[toNum(s[i])]++;
		}
		
		sort(cnt, cnt+26);
		ans = 0;
		for(i = 0; i < 26; i++)
		{
			ans += cnt[i] * (i+1);
		}
		printf("%d\n",ans);
	}
	return 0;
}




B - Glory的字符串

看到LiAlH4的完美字符串后,Glory也想开创自己的字符串。
现在Glory有一个字符串s, 包含|s|个小写字母。
每次操作他可以把一个字母变为字典序比它后一位的字母(比如a变成b,s变成t)。显然字母z是不能变化的。
现在Glory需要通过一些操作使s出现一个为abcdefghijklmnopqrstuvwxyz(字母表a-z)的子序列(注意是子序列不是子串哦~)
请你帮他给出操作后得到的s,或表明无论怎么操作都不能得到满足要求的s。

Input

输入包含一行,为字符串s,由|s|(1 ≤ |s| ≤ 105)个小写字母组成

Output


如果你可以把s变为Glory需要的样子,那么输出变化后的s 。否则输出-1。

Example


Input
aacceeggiikkmmooqqssuuwwyy
Output
abcdefghijklmnopqrstuvwxyz
Input
thereisnoanswer
Output
-1
Announcement

You are allowed to do multiple replacements for the same position of the string. Also you are allowed to leave the string as it is.


这题可能题目意思表述的不是特别清楚(或者是我语文太差),我反复看了几遍题才忐忑的试着交了一发,然后就A了。

题目大意就是通过把字符串中的某些字符变成他后面的某个字符,构造一个a-z的子序列(子序列是什么心里应该要有点什么数),但是并不限制你从哪里开始变化,也不限制你变化的次数。所以我们只要遍历一遍数组,并且用一个char变量c来记录下一个需要的字母(c的初值为'a'),找到第一个比c小的字母后(其实可能存在某种方法使这个字母不变但是也满足题意,但是找第一个比c小的字母符合贪心的原则),就将该字母变成c,且c要变成字母表的下一个字母。如果这时候c刚好是'z',那么说明已经存在满足条件的子序列,即可输出该字符串。如果整个字符串遍历完毕,则说明没有变化可以产生满足条件的子序列。

#include<stdio.h>
#include<string.h>
char s[100005];
int main()
{
	int l,i;
	char c;
	while(scanf("%s",s) != EOF)
	{
		l = strlen(s);
		c = 'a';
		i = 0;
		while(i < l && c <= 'z')
		{
			while(s[i] > c)
				i++;
			if(s[i] == c)
			{
				i++;
				c++;
			}
			else
			{
				s[i] = c;
				i++;
				c++;
			}
		}
		if(c > 'z')
			puts(s);
		else
			printf("-1\n");
	}
	return 0;
}

C - Sidney的烧烤

众所周知Sidney非常喜欢请ACM程序设计协会的小姐姐们吃烧烤。
这天晚上Sidney准备了 M 块钱,准备去菜市场给小姐姐们买烧烤。
菜市场周围有 N 家烧烤摊。第 i 家烧烤摊有 J[i] 串烧烤,总价为F[i] 元。由于Sidney和烧烤摊老板们很熟,他不需要买整数串烧烤,而是可以任意支付 F[i] * a% 元去得到 J[i] * a% 串烧烤。这里,a 表示0到100间的一个实数。

现在他将这项任务分配给了你:请告诉他,他最多能给小姐姐们买回多少烧烤。

Input

输入包含多组测试数据。

对于每组测试数据,以包含了两个非负整数 M 和 N 的一行开始。接下来的 N 行,每行相应包含了两个非负整数 J[i] 和 F[i]。

最后一组测试数据是两个 -1。所有的整数均不超过 1000。

Output

对于每组测试数据,在单独的一行中打印一个实数,精确到小数点后 3 位数,表示Sidney能买回的最多的烧烤数。

Sample Input

5 3
7 2
4 3
5 2
20 3
25 18
24 15
15 10
-1 -1

Sample Output

13.333
31.500

熟悉的人会知道,这题是背包问题的退化(不是背包问题,解法也跟背包问题没什么关系)。很显然,既然可以不买整数根烧烤,为了尽可能多的买到烧烤,我们应该找到“最便宜”的那家,然后尽可能多的买那家的烧烤,所以我们要对每家烧烤按照“性价比”排序,即按照“价格/数量”的值排序,然后不断尽可能的卖最便宜的那家烧烤。

#include<stdio.h>
struct record
{
	int x,y;
	double pri;
};
int main()
{
	int n,m,i,j;
	double sum;
	struct record t,a[1005];
	while(scanf("%d%d",&m,&n)&&m!=-1&&n!=-1)
	{
		for(i = 0; i < n; i++)
		{
			scanf("%d%d",&t.x,&t.y);
			t.pri = 1.0*t.y / t.x;
			for(j = i-1; j >= 0 && a[j].pri > t.pri; j--)
				a[j+1] = a[j];
			a[j+1] = t;
		}
		sum = 0;
		for(i = 0; i < n; i++)
		{
			if(m > a[i].y)
			{
				sum += a[i].x;
				m -= a[i].y;
			}
			else
			{
				sum += m/a[i].pri;
				break;
			}
		}
		printf("%.3lf\n",sum);
 	}
	return 0;
}

D - NaOH的讲座

NaOH计划在208组织一次讲座,为了保证每位来参加的同学都有椅子坐,他需要你帮他计算一下最少需要多少把椅子。
已知会有n个人来参加讲座,并且知道每个人体重。为了节(zeng)约(jin)空(gan)间(qing),每把椅子可以坐一个人或者两个人,椅子的承重为固定值。显然要求坐椅子的人的总重量不超过椅子的承重。

Input

第一行包含两个正整数n (0<n<=10000)和m (0<m<=2000000000),表示人数和椅子的承重。
接下来n行,每行一个正整数,表示每个人的体重,体重不超过1000000000。数据保证每个人的体重不超过m。

Output

一行一个整数,表示NaOH最少需要的椅子数。

Sample Input

3 6
1
2
3

Sample Output

2

一张凳子可以坐一个或两个人,为了尽可能的少安排凳子,我们要制定一个贪心策略。我最开始的想法是每次都让最轻的两个人先坐(我也不知道为什么这么智障),还傻乎乎的领了一个WA。其实只要稍微想一下就知道这个策略是不行的,比如椅子承重最多为10,4个人的重量为1,2,8,9,如果按照我的策略,就是1和2坐一张凳子,剩下两个人分别坐一张凳子,总共3张。但是我们发现1+9和2+8这样组合的话,就只需要两张凳子。所以正确的贪心策略是:每次找到所有人中最轻的那个和最重的那个,如果他们两个可以坐一张凳子,那显然给他们两个安排一张凳子再好不过,否则,那最重的那个就必须一个人单独坐了(最轻的都不能和他一起,其他人更不能和他一起了),所以这时候最轻的不变,只为最重的那个人安排一张凳子。

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
	int n,m,i,j,cnt;
	int a[10005];
	while(scanf("%d%d",&n,&m) != EOF)
	{
		for(i = 0; i < n ;i++)
			scanf("%d",&a[i]);
		sort(a,a+n);
		cnt = 0;
		i = 0; j = n-1;
		while(i <= j)
		{
			if(a[i] + a[j] <= m)
			{
				i++;
				j--;
				cnt++;
			}
			else
			{
				j--;
				cnt++;
			}
		}
		printf("%d\n",cnt);
	}
	return 0;
}

E - Zydsg的自行车

题目描述
匹州大学的N名成员准备包车参加红路杯大赛,为了节约经费,他们包下了Zydsg的自行车。Zydsg的自行车有后座,所以最多能载2个人(一个人骑一个人坐)。
已知N名成员第i个人骑车到达赛场或从赛场回来需要的时间为ti,每次路途中的时间等于车上成员的路途所需时间的最大值。请你求出N名成员全部到达赛场需要的最少耗时。
输入
输入包含多组测试数据。第一行含有一个正整数T,表示数据组数。
每组数据的第一行含有一个整数N。接下来的一行含有N个整数,表示ti。
输出
对于每组输入数据输出一行,每行包括1个整数,代表该组数据下全员抵达赛场的最少耗时。
样例输入
2
4
1 2 5 10
5
1 2 8 7 6
样例输出
17
22
数据范围1≤T≤20
1≤N≤1000
1≤ti≤100提示Zydsg的自行车骑到赛场后不会自动飞回来的哦~这题我做过原题,原来的题目叫“cross river”,记得这么清楚是因为从我第一次做这题到现在,我还没理解为什么可以这么贪心。但是事实证明这种贪心策略是正确的。

贪心策略是:当只有1,2,3个人时的情况特殊处理(可以直接算出结果),当人数大于等于4时,要尽可能的发挥跑的最快的两个人的作用——利用最快的两个人把最慢的两个人给运过去(为了尽可能的发挥最快的两个人的作用,不能太早把最快两个人运过去了)。假设最快的两个人是a1和a2,最慢的两个人是an-1和an,那么利用最快的两个人把最慢两个人运过去有两种方式:第一种,a1an过去,耗时an,然后a1回来,耗时a1,然后a1an-1过去,耗时an-1,然后a1回来,耗时a1,总耗时2h1+hn-1+hn;第二种:a1a2过去,耗时a2,a1回来,耗时a1,an-1an过去,耗时an,a2回来,耗时a2,总耗时h1+2h2+hn。这两种策略一定有一种是所有策略中耗时最短的,但是这两种方法的相对大小不能确定。

所以我们先把每个人的耗时排序,然后比较两种方法耗时的大小,将小的加到总时间上,则把最慢的两个人运过去了。当总人数小于4时,直接计算结果。

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
	int T,n,i,ans;
	int a[1005];
	while(scanf("%d",&T) != EOF)
	while(T--)
	{
		scanf("%d",&n);
		for(i = 0; i < n; i++)
			scanf("%d",&a[i]);
		sort(a,a+n);
		ans = 0;
		while(n >= 4)
		{
			ans += min(a[n-1]+a[0]+2*a[1], a[n-1]+a[n-2]+2*a[0]);
			n-=2;
		}
		if(n == 1)
			ans += a[0];
		else if(n == 2)
			ans += max(a[0],a[1]);
		else if(n == 3)
			ans += a[0]+a[1]+a[2];
		printf("%d\n",ans);
	}
	return 0;
}

F - Alice and Bob

Alice and Bob's game never ends. Today, they introduce a new game. In this game, both of them have N different rectangular cards respectively. Alice wants to use his cards to cover Bob's. The card A can cover the card B if the height of A is not smaller than B and the width of A is not smaller than B. As the best programmer, you are asked to compute the maximal number of Bob's cards that Alice can cover.
Please pay attention that each card can be used only once and the cards cannot be rotated.
Input
The first line of the input is a number T (T <= 40) which means the number of test cases.
For each case, the first line is a number N which means the number of cards that Alice and Bob have respectively. Each of the following N (N <= 100,000) lines contains two integers h (h <= 1,000,000,000) and w (w <= 1,000,000,000) which means the height and width of Alice's card, then the following N lines means that of Bob's.
Output
For each test case, output an answer using one line which contains just one number.
Sample Input
2
2
1 2
3 4
2 3
4 5
3
2 3
5 7
6 8
4 1
2 5
3 4 
Sample Output
1
2

我觉得本次比赛最难的题就是这个了(可能是因为我比较菜吧),我苦思冥想很久想不到很好的办法,最后还是百度出来的,所以如果我写的不好还是建议看官自行百度。

考虑一张卡片要覆盖另一张卡片,我们要考虑两个因素:长和宽。同时考虑这两个因素的比较或许有些困难,但是只考虑长或者只考虑宽时,问题是非常简单的,所以我们可以先对长进行排序,在找一张卡片能覆盖的牌时,只需要从头遍历数组,直到这个数组的长大于当前卡片的长为止。一张卡片可能覆盖多张卡片,这时候为了保证所有卡片能尽可能多的覆盖对方的卡片,我们应该选择这张卡能覆盖的宽度最大的卡片。

接下来考虑一下复杂度的问题:排序O(nlogn),遍历我方的n张卡O(n),遍历每张卡时,要找这张卡能覆盖的宽度最大的卡O(n),所以总的复杂度是O(nlogn)+O(n²)=O(n²),这个复杂度是会TLE的。这时候只有两种选择,第一,优化算法,即采用更好的贪心策略(我连这种贪心策略都没想出来,更别说更好的贪心策略了);第二,优化数据结构,采用空间换时间之类的方法。

我们考虑一下我们需要做的操作:排序肯定是需要的,此外,每次判断我方的卡片,我们要将对方卡片中所有长度比这张卡小的卡片加入考虑范围,即对我们所选的数据结构插入一个元素,然后要找到比我方当前卡片宽度小且宽度尽可能大的卡片,即找某个元素的上界,最后要保证每张卡片只能用一次,所以用过的卡片要从中删除。即涉及的操作有:插入,删除,找上界。

这时候可以采用BST(二叉搜索树),BST是一个树形结构,且对于树中的每个节点,其左子树要么为空,要么子树中任意一个结点的值都比这个结点小,其右子树要么为空,要么子树中任意一个结点的值都大于等于这个结点。但是当插入值的顺序是有序的时候,BST会退化成一个一维数组,所以考虑特殊数据的话复杂度还是O(n²),所以还要对BST进行AVL优化,AVL表示二叉平衡树,二叉平衡树中,任意一个结点的左右子树的树高之差绝对值小于等于1(认为空子树的高度为0)。

遗憾的是AVL树和BST树的代码我都没写过(约等于写不出来),所以这时候就有一个非常神奇的东西叫做STL。STL里面有一个更神奇的东西叫做multiset,至于这个东西,也是我百度才知道的,它能满足我刚才说的插入、删除和找上界等操作,且每个操作的复杂度均为O(logn),所以用了multiset过后,我们的复杂度变成了排序O(nlogn),遍历我方n张卡O(n),遍历每张卡时涉及的插入、删除、检索等操作的复杂度均为O(logn),即处理每张卡的复杂度为O(logn),故总的复杂度为O(nlogn)+O(nlogn)=O(nlogn)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<set>
#define N 100005
using namespace std;
typedef struct
{
	int h,w;
} node;
node a[N],b[N];
bool cmp(node a, node b)
{
	if(a.h > b.h)
		return false;
	else if(a.h == b.h && a.w > b.w)
		return false;
	return true;
}
int main()
{
	int T,n,i,j,ans;
	multiset<int> s;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		for(i = 0; i < n; i++)
			scanf("%d%d",&a[i].h,&a[i].w);
		for(i = 0; i < n; i++)
			scanf("%d%d",&b[i].h,&b[i].w);
		sort(a,a+n,cmp);
		sort(b,b+n,cmp);
		ans = 0;
		s.clear(); 
		for(i = 0, j = 0; i < n; i++)//遍历数组a 
		{
			while(j < n && a[i].h >= b[j].h)
			{
				s.insert(b[j].w);//将数组b中比a[i].h小的全部入队 
				j++;
			}
			set<int>::iterator it = s.upper_bound(a[i].w);//找到a[i].w的最小上界 
			if(s.size() > 0 && it != s.begin())//上界不取等,找前面一个 
				it--;
			if(s.size() > 0 && *it <= a[i].w)//满足条件,出队 
			{
				ans++;
				s.erase(it);
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}


G - Robot Vacuum Cleaner

Pushok the dog has been chasing Imp for a few hours already.

Fortunately, Imp knows that Pushok is afraid of a robot vacuum cleaner.

While moving, the robot generates a stringt consisting of letters 's' and 'h', that produces a lot of noise. We definenoise of string t as the number of occurrences of string "sh" as asubsequence in it, in other words, the number of such pairs (i, j), thati < j and and.

The robot is off at the moment. Imp knows that it has a sequence of stringsti in its memory, and he can arbitrary change their order. When the robot is started, it generates the string t as a concatenation of these strings in the given order. The noise of the resulting string equals the noise of this concatenation.

Help Imp to find the maximum noise he can achieve by changing the order of the strings.

Input

The first line contains a single integern (1 ≤ n ≤ 105) — the number of strings in robot's memory.

Nextn lines contain the stringst1, t2, ..., tn, one per line. It is guaranteed that the strings are non-empty, contain only English letters 's' and 'h' and their total length does not exceed 105.

Output

Print a single integer — the maxumum possiblenoise Imp can achieve by changing the order of the strings.

Example
Input
4
ssh
hs
s
hhhs
Output
18
Input
2
h
s
Output
1
Note

The optimal concatenation in the first sample isssshhshhhs.


这题的大意是说有n个由's'和'h'组成的字符串,然后我们可以自由选择这些字符串的顺序,组合要尽可能的使最后拼接成的新字符串中,'sh'的序对数目尽可能的多('s'和'h'不一定要连续),问最多有多少个'sh'序对。

每个'sh'序对都是以'h'结尾,所以说一个h对应的'sh'序对的数目就是在这个'h'前面的所有's'的数目。所以我们要尽量让's'放在前面,并且'h'要尽量放在后面。这个时候可能会想到一种可能的贪心策略:让含's'数目多的放在前面。但是通过样例我们就发现这种策略是不行的,因为它没有满足“'h'要尽量放在后面”这一条。正确的贪心策略是:把's'和'h'数目之比更高的字符串放在前面。所以我们要对每个字符串的's'和'h'之比进行排序,然后计算'sh'的个数。

关于计算'sh'个数,先拼接起来再数每个'h'前面有多少's'显然是不行的。只能这样考虑:每个'h'对应的'sh'序对,有一部分的's'是来自于和'h'同一个字符串中的,另一部分是来自于排在这个字符串前面的字符串中的。这时候我们只要知道前面的字符串有多少个's'就行了而不需要知道具体是怎么分配的。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 99999999
using namespace std;
typedef struct
{
	double per;
	long long s,h;
} node;
node a[100005];
char s[100005];
bool ccmp(node a, node b)
{
	if(a.per > b.per)
		return true;
	return false;
}
int main()
{
	int n,i,j,l;
	long long ans,cnt;
	while(scanf("%d",&n) != EOF)
	{
		getchar();
		ans = 0;
		for(i = 0; i < n; i++)
		{
			gets(s);
			l = strlen(s);
			a[i].h = a[i].s = 0;
			for(j = 0; j < l; j++)
			{
				if(s[j] == 's')
					a[i].s++;
				else
				{
					a[i].h++;
					ans += a[i].s;
				}
			}
			if(a[i].h == 0)
				a[i].per = inf;
			else
				a[i].per = (double)a[i].s/a[i].h;
		}
		sort(a,a+n,ccmp);
		cnt = a[0].s;
		for(i = 1; i < n; i++)
		{
			ans += a[i].h*cnt;
			cnt += a[i].s;
		}
		printf("%lld\n",ans);
	}
	return 0;
}

H - Tian Ji -- The Horse Racing

Here is a famous story in Chinese history.

"That was about 2300 years ago. General Tian Ji was a high official in the country Qi. He likes to play horse racing with the king and others."

"Both of Tian and the king have three horses in different classes, namely, regular, plus, and super. The rule is to have three rounds in a match; each of the horses must be used in one round. The winner of a single round takes two hundred silver dollars from the loser."

"Being the most powerful man in the country, the king has so nice horses that in each class his horse is better than Tian's. As a result, each time the king takes six hundred silver dollars from Tian."

"Tian Ji was not happy about that, until he met Sun Bin, one of the most famous generals in Chinese history. Using a little trick due to Sun, Tian Ji brought home two hundred silver dollars and such a grace in the next match."

"It was a rather simple trick. Using his regular class horse race against the super class from the king, they will certainly lose that round. But then his plus beat the king's regular, and his super beat the king's plus. What a simple trick. And how do you think of Tian Ji, the high ranked official in China?"



Were Tian Ji lives in nowadays, he will certainly laugh at himself. Even more, were he sitting in the ACM contest right now, he may discover that the horse racing problem can be simply viewed as finding the maximum matching in a bipartite graph. Draw Tian's horses on one side, and the king's horses on the other. Whenever one of Tian's horses can beat one from the king, we draw an edge between them, meaning we wish to establish this pair. Then, the problem of winning as many rounds as possible is just to find the maximum matching in this graph. If there are ties, the problem becomes more complicated, he needs to assign weights 0, 1, or -1 to all the possible edges, and find a maximum weighted perfect matching...

However, the horse racing problem is a very special case of bipartite matching. The graph is decided by the speed of the horses --- a vertex of higher speed always beat a vertex of lower speed. In this case, the weighted bipartite matching algorithm is a too advanced tool to deal with the problem.

In this problem, you are asked to write a program to solve this special case of matching problem.
Input
The input consists of up to 50 test cases. Each case starts with a positive integer n (n <= 1000) on the first line, which is the number of horses on each side. The next n integers on the second line are the speeds of Tian’s horses. Then the next n integers on the third line are the speeds of the king’s horses. The input ends with a line that has a single 0 after the last test case.
Output
For each input case, output a line containing a single number, which is the maximum money Tian Ji will get, in silver dollars.
Sample Input
3
92 83 71
95 87 74
2
20 20
20 20
2
20 19
22 18
0
Sample Output
200
0
0
问题取自于一个经典的故事:田忌赛马,赛马赢一局可以获得200,输一局要失去200,平局则不输不赢,给出马的属性值,问最多能赢多少钱。
田忌赛马的思路可以说成是“让对方的良马发挥最小的作用,让我方的良马发挥最大的作用”,也就是尽量用己方最差的马消耗掉对方最强的马,用我方最强的马赢过对方跑得尽可能快的马。所以我们自然可以想到这样的贪心策略:1.当我方的快马(即跑的最快的马,下同)比对方的快马慢时,用我方的慢马(即跑的最慢的马,下同)和对方的快马比。2.当我方的快马比对方的快马快时,用我方的快马和对方的快马比。
但是还有第三种情况,即3.我方的快马和对方的快马一样快。这种情况我暂时还想的不是特别透彻,我知道的答案是:这时候选择比较双方的慢马,如果我方的慢马比对方的快,则先让两匹慢马比较,否则,让我方的慢马消耗掉对方的快马。

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
	int n,i,j,ii,jj,ans;
	int a[1005],b[1005];
	while(scanf("%d",&n)&&n)
	{
		for(i = 0; i < n; i++)
			scanf("%d",&a[i]);
		for(i = 0; i < n; i++)
			scanf("%d",&b[i]);
		sort(a,a+n);
		sort(b,b+n);
		i = ii = 0;
		j = jj = n-1;
		ans = -n*200;
		while(i <= j)
		{
			if(a[j] < b[jj])//a最快比b最快慢 
			{
				i++;//最慢和最快打 
				jj--;
			}
			else if(a[j] > b[jj])//a最快比b最快快 
			{
				j--;//最快和最快打 
				jj--;
				ans += 400;
			}
			else//两个最快相等 
			{
				if(a[i] > b[ii])//a最慢比b最慢快 
				{
					i++;//最慢和最慢打 
					ii++;
					ans += 400;
				}
				else if(a[i] <= b[ii])//a最慢比b最慢慢或相等 
				{
					if(a[i] == b[jj])
						ans += 200;
					i++;//最慢和最快打 
					jj--;
				}
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值