CF777B Game of Credit Cards

Posted whx666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF777B Game of Credit Cards相关的知识,希望对你有一定的参考价值。

题目链接

一道打着洛谷黑题招牌的简单贪心

题目

题目描述

有两个人S和M,他们每人有一段长度为N的数字,两个人在每一轮游戏中都可以按顺序拿出一个数字,谁的数字小谁就接受一次惩罚。若相等两者都没有惩罚。另外,M珂以重新安排自己数字的顺序,问 M的最少被惩罚次数 和 S的最多被惩罚次数 是多少。

 

输入输出格式

输入格式

输入的第一行包含一个整数n (1<=n<=1000)——S和M将要使用的纸牌中的数字。

第二行包含n个没有空格数字——S的数字。

第三行包含n个没有空格数字——M的数字。

输出格式

第一行先把M最少受罚次数输出。

第二行输出S最多的受罚次数。

 

输入输出样例

输入样例#1 

3
123
321

输出样例#1

0
2

输入样例#2 

2
88
00

输出样例#2

2
0

 

题目思路

有点类似于田忌赛马的问题, 可以想到用贪心的最优策略

第一问

求S最小受罚次数

M可以按任意顺序拿出数字,枚举遍历S中的每一个数,对于每一个数 a 只有两种情况:

1

W中有还未用且 ≥ a 的数,此时选满足条件的最小的数

2

W中的数都 < a 的数, 此时选未用的数中最小的数

代码

 

for (int i = 1; i <= len; i++) {
		bool ok = 0;
		for (int j = 1; j <= len; j++) 
		    if (a[j] >= b[i] and !used[j])  {ok = 1, used[j] = 1; break;}	
		if (!ok)
			for (int j = 1; j <= len; j++)
				if (!used[j])  {used[j] = 1, ans1++;   break;}
	}

 

  

 

 

第二问

求M最大受罚数

做法相似,枚举遍历S中的每一个数,对于每一个数 a 只有两种情况:

1

W中有还未用且 > a 的数,此时选满足条件的最小的数

2

W中的数都   ≤  a 的数, 此时选未用的数中最小的数

代码

 

for (int i = 1; i <= len; i++) {
		bool ok = 0;
		for (int j = 1; j <= len; j++) 
		    if (a[j] > b[i] and !used[j])  {ok = 1, used[j] = 1, ans2++; break;}	
		if (!ok)
			for (int j = 1; j <= len; j++)
				if (!used[j])  {used[j] = 1;   break;}
	}

 

 

完整代码

#include <bits/stdc++.h>
using namespace std;
char a[1005], b[1005];
bool used[1005];  //used记录是否被用 
int len, ans1, ans2; //ans1记录 M 最少受罚次数, ans2记录 S 最多受罚次数 
int main() {
	scanf ("%d %s %s", &len, b + 1, a + 1);
	sort (a + 1, a + len + 1);
	//第一问: 
	for (int i = 1; i <= len; i++) {
		bool ok = 0;   //ok记录是否有满足要求的数 
		for (int j = 1; j <= len; j++) 
		    if (a[j] >= b[i] and !used[j])  {ok = 1, used[j] = 1; break;} 
		//如果没有则选最小的数	
		if (!ok)
			for (int j = 1; j <= len; j++)
				if (!used[j])  {used[j] = 1, ans1++;   break;}  //此时受罚次数 +1; 
	}
	memset (used, 0, sizeof (used));   //清零used数组 
	//第二问:  
	for (int i = 1; i <= len; i++) {
		bool ok = 0;   //ok记录是否有满足要求的数 
		for (int j = 1; j <= len; j++) 
		    if (a[j] > b[i] and !used[j])  {ok = 1, used[j] = 1, ans2++; break;}
		//如果没有则选最小的数	
		if (!ok)
			for (int j = 1; j <= len; j++)
				if (!used[j])  {used[j] = 1;   break;}   //此时不受罚次数 +1; 
	}
    printf ("%d
%d", ans1, ans2);
    return 0;
}

 

以上是关于CF777B Game of Credit Cards的主要内容,如果未能解决你的问题,请参考以下文章

CF1349C Orac and Game of Life题解

cf1523A. Game of Life

CF1350E Orac and Game of Life(BFS)

并不对劲的CF1349B&C:Game of Median Life

CF809C Find a car

cf299C Weird Game