[08NOIP universal seat row group]

http://ybt.ssoier.cn:8088/problem_show.php?pid=1943
[title] Description
class when there are always some people around the students and around whispering to each other, something that makes primary school teacher is very troublesome thing. However, snow teacher found some interesting phenomena, when the students of seating finalized, only limited D will whisper when the students in class. Students in the classroom would be sitting M rows and N columns, the students sitting position of the first row of ii jj column is the (i, j), in order to facilitate the students out, provided the K transverse channels in the classroom, L longitudinal channel strip. So, smart snow thought of a way, perhaps the problem of students in class whispering to each other can be reduced: She intends to rearrange tables and chairs, tables and chairs to change the position of the channel between the students, because if a channel separating the two would whisper students, they would not whisper a.

Would you please write a program to snow, give the best channel division scheme. Under this scheme, the minimum number of students in class whispering.

[Input]
The first line, 55 separated by a space of a certificate, namely M, N, K, L, D (2≤N, M≤1000,0≤K <M, 0≤L <N, D ≤2000) M, N, K, L, D (2≤N, M≤1000,0≤K <M, 0≤L <N, D≤2000).

Next row D, each row having four integers separated by a space. I-th row of four certificates Xi, Yi, Pi, OiXi, Yi, Pi, Oi, expressed sitting position (Xi, Yi) and (Pi, Oi) of two students will whisper (before and after they enter adjacent or guarantee about adjacent).

Input data to ensure the uniqueness of the best programs.

[Output]
a total of two lines.

The first line contains integers KK, a1, a2 ...... AK, a1 represents the row between the first row and a1 + 1, a2 of the first row and the line a2 + 1, ..., aK first row and the first row aK + 1 to open the way between, where ai <ai + 1, between every two integers separated by a space (no end of line spaces).

The second line contains L integers, B1B2 ...... bL, b1 represents a column between the first column and b1 + 1, b2 between the first column and the row b2 + 1, ..., bL to between the first row and first column bL + 1 open channel, wherein the bi <bi + 1, between every two integers separated by a space (no end of line spaces).

[Sample] input
. 4 2. 3. 1. 5
. 4. 3. 4 2
2. 3. 3. 3
2 2. 5. 4
[Sample] Output
2
2. 4

Subject a little long, but this question is examined greedy + sort; problem to be solved is: Find the first k, l before a vertical row of horizontal rows;

  • How to find the first k horizontal, it is clear that most of the students speak horizontal horizontal, separated only need the most, so it is necessary to find the most horizontal speaking before students of k;
  • How to find before l a tandem, empathy.

Method a: fast row greedy +

#include<bits/stdc++.h>
using namespace std;
#define N 1005
int aK[N], aL[N];//横排的前k个、纵排的前l个
int a1[N], b1[N];//横纵坐标出现的次数
int main(){
	int m, n, k, l, d, x1, y1, x2, y2;
	cin >> m >> n >> k >> l >> d;
	for(int i=1; i<=d; i++){//统计横纵坐标出现的次数
		cin >> x1 >> y1 >> x2 >> y2;
		if(x1 == x2)
			b1[(y1>y2)?y2:y1]++;
		else if(y1 == y2)
			a1[(x1>x2)?x2:x1]++;
	}
	for(int i=1; i<=k; i++){//通过比较大小,拿到a1数组(横坐标)中的前k值
		int mmax = 0, x;
		for(int j=1; j<=m; j++){
			if(a1[j] > mmax)
				mmax = a1[j], x = j;
		}
		aK[i] = x;
		a1[x] = 0;
	}
	for(int i=1; i<=l; i++){//通过比较大小,拿到b1数组(纵坐标)中的前l值
		int mmax = 0, x;
		for(int j=1; j<=n; j++){
			if(b1[j] > mmax)
				mmax = b1[j], x = j;
		}
		aL[i] = x;
		b1[x] = 0;
	}
	sort(aK+1, aK+k+1);
	sort(aL+1, aL+l+1);
	for(int i=1; i<=k; i++)
		cout << aK[i] << " ";
	cout << endl;
	for(int i=1; i<=l; i++)
		cout << aL[i] << " ";
	cout << endl;
	return 0;
}

Method two: greedy ordering structure +

#include<bits/stdc++.h>
using namespace std;
#define N 1005
struct node{
	int t, x;
}aK[N], bL[N];
bool cmp_big(node p, node q){
	return p.t > q.t;
}
bool cmp_small(node p, node q){
	return p.x < q.x;
}
int main(){
	int m, n, k, l, d, x1, y1, x2, y2;
	cin >> m >> n >> k >> l >> d;
	for(int i=1; i<=d; i++){
		cin >> x1 >> y1 >> x2 >> y2;
		if(x1 == x2){
			bL[(y1>y2)?y2:y1].t++;//t:出现次数times
			bL[(y1>y2)?y2:y1].x = (y1>y2)?y2:y1;//x:出现的数
		}
		else if(y1 == y2){
			aK[(x1>x2)?x2:x1].t++;
			aK[(x1>x2)?x2:x1].x = (x1>x2)?x2:x1;
		}
	}
	sort(aK+1, aK+m+1, cmp_big);//按照出现次数从大到小排序,找到前k个
	sort(bL+1, bL+n+1, cmp_big);//按照出现次数从大到小排序,找到前l个
	sort(aK+1, aK+k+1, cmp_small);//将前k个按照x(数)从小到大排序
	sort(bL+1, bL+l+1, cmp_small);//将前l个按照x(数)从小到大排序
	for(int i=1; i<=k; i++)
		cout << aK[i].x << " ";
	cout << endl;
	for(int i=1; i<=l; i++)
		cout << bL[i].x << " ";
	cout << endl;
	return 0;
}
Published 15 original articles · won praise 10 · views 209

Guess you like

Origin blog.csdn.net/qq_39053800/article/details/104249915