【08NOIPユニバーサルシート行グループ]

http://ybt.ssoier.cn:8088/problem_show.php?pid=1943
[タイトル]説明
クラスの生徒の周りに、互いにささやく周りの何人かの人々が常に存在する場合には、小学校の先生になり、何かが非常に面倒なことです。座席の学生が確定したときしかし、雪の先生が、いくつかの興味深い現象を発見し、限られたDは、クラスの時に学生をささやくます。教室の学生は、M行N列に座っているであろう、II JJ列の最初の行の位置に座って、学生は、(i、j)は、学生を容易にするために、L、教室でK横チャネルを提供縦方向のチャンネルストリップ。だから、スマート雪は、おそらくお互いにささやくクラスの生徒の問題を低減することができ、方法を考えた:彼女は2チャネル分離がささやくかのために、学生との間のチャネルの位置を変更するためにテーブルと椅子、テーブルと椅子を再配置する予定学生、彼らはないささやきだろう。

あなたは最高のチャネル分割方式を与え、雪にプログラムを書いてくださいだろう。このスキームの下では、クラスの生徒の最小数はささやきます。

[入力]
証明書、すなわち、M、N、K、L、のスペースで分離された第1ライン、55 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)。

次の行D、4つの整数を有し、各列は、空白で区切られました。彼らは、隣接または保証を入力する前と後に発現4つの証明書西、李、パイ、OiXi、李、パイ、大井のI行目は、2人の学生の位置(xi、yi)および(パイ、大井)を座って(ささやくます隣接する程度)。

最高のプログラムの一意性を確保するために、入力データ。

[出力]
2つのラインの合計。

最初の行は整数KK、A1、A2 ...... AKが含まれ、A1は、最初の行の間とA1 + 1、A2 1行ラインA2 + 1、...、AK 1行1列AK + 1の行を表しますここで、との間の道を開くには空間(行間隔の終わり)で区切られた各2つの整数の間に、+ 1を愛<愛。

2行目はLの整数、B1B2が...... BLは、B1が最初の列と行B2 + 1との間の最初の列とB1 + 1、B2間のカラムを表すが含ま、...、BLに1行1列目の間bLを+ 1空間(行間隔の終わり)で区切られた各2つの整数の間でオープンチャネル、1 +請求BI <BI、。

[サンプル]入力
4 2. 3. 1. 5
4 3 4 2
2 3 3 3
2 2 5 4
[サンプル]出力
2
2 4

少し長い被験者が、この問題は、貪欲+ソートを検査される。解決すべき問題は、水平行の垂直方向の行の前に最初のK、Lを探します。

  • 最初のk水平を見つけるために、どのように、学生のほとんどは、水平方向の水平を話すことは、kの学生の前にほとんど水平話すを見つける必要があるので、ほとんどを必要とするだけで分離することは明らかです。
  • どのように、Lの前に共感をタンデムを検索します。

方法A:高速行貪欲+

#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;
}

方法2:貪欲な秩序構造+

#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;
}
公開された15元の記事 ウォン称賛10 ビュー209

おすすめ

転載: blog.csdn.net/qq_39053800/article/details/104249915
おすすめ