[codeforces 1374E1] Reading Books (easy version) 巧妙配对

Codeforces Round #653 (Div. 3)   参与排名人数11687

[codeforces 1374E1]    Reading Books (easy version)    巧妙配对

总目录详见https://blog.csdn.net/mrcrack/article/details/103564004

在线测评地址http://codeforces.com/contest/1374/problem/E1

ProblemLangVerdictTimeMemory
E1 - Reading Books (easy version) GNU C++17Accepted124 ms6000 KB

题目大意:给定一堆书,有只有Alice喜欢的,有只有Bob喜欢的,也有两者都喜欢的,选出Alice喜欢的k本书,Bob喜欢的k本书,两种选择可以有重复,组成一个新集合,要求新集合对应的总阅读时间最少,输出这个最少时间。

基本思路:按阅读时间,自小到大,将只有Alice喜欢的排序,将只有Bob喜欢的排序,将两者自小到大配对,配成两者都喜欢的,即两本书的阅读时间,合并成一本书的阅读时间,归类为两者都喜欢的书。

证明:只有Alice喜欢的书,与只有Bob喜欢的数量是一致的。

都喜欢的书有c本,只有Alice喜欢的有a本,只有Bob喜欢的有b本。

因Alice喜欢的书有k本,k=c+a;

因Bob喜欢的书有k本,k=c+b;

c+a=c+b

a=b.

样例分析如下:

8 4
7 1 1
2 1 1
4 0 1
8 1 1
1 0 1
1 1 1
1 0 1
3 0 0

18

1 0 1
1 0 1
4 0 1

1 1 1
2 1 1
7 1 1
8 1 1

被选中的书:
1 1 1
2 1 1
7 1 1
8 1 1

1+2+7+8=18
总耗时18

AC代码如下:

#include <cstdio>
#include <algorithm>
#define maxn 200010
using namespace std;
int a[maxn],b[maxn],c[maxn],an,bn,cn;
int main(){
	int n,k,i,t,x,y,ans=0;
	scanf("%d%d",&n,&k);
	for(i=1;i<=n;i++){
		scanf("%d%d%d",&t,&x,&y);
		if(x==1&&y==1)c[++cn]=t;
		else if(x==1)a[++an]=t;
		else if(y==1)b[++bn]=t;
	}
	sort(a+1,a+1+an);
	sort(b+1,b+1+bn);
	n=min(an,bn);
	for(i=1;i<=n;i++)
		c[++cn]=a[i]+b[i];//两本各自喜欢的书合成一本大家都喜欢的书
	sort(c+1,c+1+cn);
	if(cn<k) printf("-1\n");
	else{ 
		for(i=1;i<=k;i++)ans+=c[i];
		printf("%d\n",ans);
	}
	return 0;
}

收获:main函数中,若返回值是1,即return 1;(本应是return 0;),测评系统会报错Runtime error on test 3。