1109 Group Photo (25 分)
模拟题~。
题意
N个人排成K排来照相,规则如下:
(1) 除了最后一排(个子最高的那排)外,其余所有排的人数均为N/K (向下取整)。,
(2) 后排所有人的身高都大于前排所有人的身高。
(3) 对每一排来说,最高的人站在中间;在此基础上,该排的其他人按照左右交替的方式排在中间的人的两侧,例如中间的人的身高是190,那么第二高188应当排在190左侧(照相师视角),第三高186应当排在190右侧,第四高175应当排在188左侧,第五高170应当排在186右侧,最后该排的结果将为175 188 190 186 170。
(4) 身高相同时以姓名字典序小的先排。
最后从后排往前排依次输出每排的人的姓名。
思路
我是直接用双端队列模拟的。
const int N=10010;
struct Node
{
string name;
int height;
bool operator<(const Node &W) const
{
if(height != W.height) return height > W.height;
return name < W.name;
}
}a[N];
deque<string> row[N];
int n,k;
int main()
{
cin>>n>>k;
for(int i=0;i<n;i++) cin>>a[i].name>>a[i].height;
sort(a,a+n);
int cnt=n/k;
int tot=0;
for(int i=0;i<n;i+=cnt)
{
int r=i+cnt-1;
if(i == 0) r+=n%cnt;
int t=0;
int l=i;
while(l<=r)
{
if(t == 0)
row[tot].push_back(a[l++].name);
else
row[tot].push_front(a[l++].name);
t^=1;
}
tot++;
if(i == 0) i+=n%cnt;
}
for(int i=0;i<tot;i++)
{
for(int j=0;j<row[i].size();j++)
if(j) cout<<' '<<row[i][j];
else cout<<row[i][j];
cout<<endl;
}
//system("pause");
return 0;
}
以下为晴神思路:
由于除最后一排外其他排均为N/K人,因此最后一排的人数为N-(N-1)*(N/K)。对于某一排来说,每次都是左右交替进行人的放置,因此按该排内部的序号来说一定是一侧奇数一侧偶数。例如一排中有7个人时的最终排列效果为5310246,显然左侧的5 3 1是奇数递减序列,右侧的0 2 4 6是偶数递增序列。
通过归纳总结可以知道,假设某排的人数为num,那么该排的奇数部分的最大数为小于num的最大奇数,最小数为1;偶数部分的最小数为0,最大数为小于num的最大偶数。