1. 程式人生 > >1055 集體照——c實現

1055 集體照——c實現

1055 集體照 (25 point(s))

拍集體照時隊形很重要,這裡對給定的 N 個人 K 排的隊形設計排隊規則如下:

  • 每排人數為 N/K(向下取整),多出來的人全部站在最後一排;

  • 後排所有人的個子都不比前排任何人矮;

  • 每排中最高者站中間(中間位置為 m/2+1,其中 m 為該排人數,除法向下取整);

  • 每排其他人以中間人為軸,按身高非增序,先右後左交替入隊站在中間人的兩側(例如5人身高為190、188、186、175、170,則隊形為175、188、190、186、170。這裡假設你面對拍照者,所以你的左邊是中間人的右邊);

  • 若多人身高相同,則按名字的字典序升序排列。這裡保證無重名。

現給定一組拍照人,請編寫程式輸出他們的隊形。

輸入格式:

每個輸入包含 1 個測試用例。每個測試用例第 1 行給出兩個正整數 N(≤10​4​​,總人數)和 K(≤10,總排數)。隨後 N 行,每行給出一個人的名字(不包含空格、長度不超過 8 個英文字母)和身高([30, 300] 區間內的整數)。

輸出格式:

輸出拍照的隊形。即K排人名,其間以空格分隔,行末不得有多餘空格。注意:假設你面對拍照者,後排的人輸出在上方,前排輸出在下方。

輸入樣例:

10 3
Tom 188
Mike 170
Eva 168
Tim 160
Joe 190
Ann 168
Bob 175
Nick 186
Amy 160
John 159

輸出樣例:

Bob Tom Joe Nick
Ann Mike Eva
Tim Amy John

思路:

這道題是PAT乙級考試五道題目裡面最難的題了。可以看出考察的知識點還是那些,排序演算法、搜尋演算法。但是題目設定條件比較複雜。所以,複雜的題目最終還是要歸結到運用數學知識來解決。類似這樣的題目先想清楚一行如何排列,然後其他的類推就很容易了。

程式碼:

//1055. 集體照v1
#include <iostream>
#include <algorithm> 
#include <vector>
using namespace std;
struct node
{
	string name;
	int height;
};
int cmp(struct node a,struct node b){
	return a.height !=b.height?a.height >b.height :a.name<b.name;
}

int main(){
	int n,k,m;
	cin>>n>>k;
	vector<node> stu(n);
	int i;
	for(i=0;i<n;i++){
		cin>>stu[i].name;
		cin>>stu[i].height;
	}
	sort(stu.begin(),stu.end(),cmp);
	int t=0,row=k;
	while(row){
		if(row==k)	m=n-n/k*(k-1);
		else	m=n/k;
		vector<string> stemp(m);
		stemp[m/2]=stu[t].name;	
		//左邊一列
		int j=m/2-1;
		int i;
		for(i=t+1;i<t+m;i=i+2)	stemp[j--]=stu[i].name;
		//右邊一列 
		j=m/2+1;
		for(i=t+2;i<t+m;i=i+2)	stemp[j++]=stu[i].name;
		//輸出當前排
		cout<<stemp[0];
		for(i=1;i<m;i++)	cout<<" "<<stemp[i];
		cout<<endl;
		t=t+m;
		row--; 
	}
	return 0;
}