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的最大偶数。

原文地址:https://www.cnblogs.com/fxh0707/p/14425940.html