洛谷 P1056 排座椅(贪心)

题目链接:点击这里
洛谷 P1056 排座椅(贪心)_第1张图片
洛谷 P1056 排座椅(贪心)_第2张图片
贪心规律:不管是行还是列,优先输出价值大(即能把交头接耳同学尽可能多的分开)的序号。

使用结构体记录序号mark和该号序的价值,分别输入统计所有行序号和所有列序号的价值。

因此,只需对统计好的行结构体数组、列结构体数组按价值从大到小排序,分别取前K和前L个的位置坐标即可,可以证明这是最优的思路。

要注意有坑。在找出我们需要的位置时,别忘了对位置再从小到大排个序输出,不然WA声一片。

#include
#include
#include
#include
#include
#include
#include
#include
#include

using namespace std;
typedef long long ll;
const int MOD = 10000007;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);
const int maxn = 1010;

struct node{
	int mark;
	int value;
}row[maxn],col[maxn];

int a[maxn],b[maxn];

//按价值从大到小排序 
int cmp(node a, node b)
{
	return a.value > b.value;
}

int main()
{
	int M,N,K,L,D;
	scanf("%d%d%d%d%d",&M,&N,&K,&L,&D);
	
	//初始化所有的行序号、列序号 
	for(int i=1;i<maxn;i++)
	{
		row[i].mark = i;
		col[i].mark = i;
	}
	
	int X,Y,P,Q;
	for(int i=0;i<D;i++)
	{
		scanf("%d%d%d%d",&X,&Y,&P,&Q);
		//分别统计行序号、列序号的价值 
		if(Y==Q)
			row[min(X,P)].value++;
		if(X==P)
			col[min(Y,Q)].value++;
	}
	
	//按价值从大到小排序 
	sort(row+1,row+maxn,cmp);
	//直接输出前K个序号会WA掉
	//将前K个序号保存一下按从小到大顺序输出 
	for(int i=1;i<=K;i++)
		a[i] = row[i].mark;
	sort(a+1,a+K+1);
	for(int i=1;i<=K;i++)
	{
		printf("%d",a[i]);
		if(i<K)
			printf(" ");
	}
	
	printf("\n");
	
	//按价值从大到小排序 
	sort(col+1,col+maxn,cmp);
	//直接输出前L个序号会WA掉
	//将前L个序号保存一下按从小到大顺序输出
	for(int i=1;i<=L;i++)
		b[i] = col[i].mark;
	sort(b+1,b+L+1);
	for(int i=1;i<=L;i++)
	{
		printf("%d",b[i]);
		if(i<L)
			printf(" ");
	}
	return 0;
}

你可能感兴趣的:(贪心)