9503 懒人选座位 9503 懒人选座位 Description 输入格式 输出格式 输入样例 输出样例 提示 来源 作者

时间限制:500MS  内存限制:65535K
提交次数:0 通过次数:0

题型: 编程题   语言: G++;GCC

 

Description

    在ACM混了一年之后,我终于有机会在新生赛出题了。然后我瞬间出了一道题。
    (好吧,我承认,我只是翻译了原题而已╮(╯▽╰)╭)
发过去给lyd,然后马上被鄙视了:“这么简单的题目?” 哎,没办法啊,过去一年我就是切水题过来的~~
其实我个人认为这题还是挺有趣的……水水更健康吗……大家一起来切水题吧!
相信大家都有这样的体验吧:课室里每行座位间的间距都很小,上课的时候,早到的同学都要侧身或者站起来,让其他同学坐进去里面。
╮(╯▽╰)╭ 我是一个很懒的人,假如我是第一个到场,我希望选了座位之后,侧身让位的次数能够尽量地少…… 现在有一排n个空座位,从左到右分别编号1 ~ n。 然后其他同学都会选定一个座位然后走进去,并且进去的方位(左边or右边)服从以下的规定: 1. 选择途经人数最少的方向进入 ① ② 我 ③ ④ ⑤ ⑥ 比如第二个到的同学选定了3号座位,他会选择从右边进入,我不用让位。 2. 当两端途经的人数一样时,选择靠近自己座位的那边进入。 ① ② 我 ③ ④ ⑤ 有人 ⑥ 比如第三个到的同学选择坐3号座位,他会从左边进入,然后我要让位。 3. 都一样时,随机选进入方位。 现在的问题是,当我选择坐第k个座位后,我想知道在最坏的情况下,要侧身让位多少次?




输入格式

    有若干组数据,以EOF判定结束。
    每组数据第一行有两个整形n(1~ 30)和q(1~30)。分别表示座位数和查询次数。接下来一行有q个整型。k1,k2……kq,分别表示我选择坐第k个座位。数据以空格分隔。



输出格式

    每组数据一行,对于每次查询,输出一个结果,以空格分隔。



 

输入样例

4 4
1 2 3 4
5 5
1 2 3 4 5



 

输出样例

1 0 0 1
2 1 0 1 2



 

提示

    四个座位的时候,我选定座位①后,若第二个人选了③or④,当第三个人选②,我就要让位一次,这个是最坏的情况。
    EOF结束即是数据读入以文件结束符结束。即输入输出类似如下(当然变量名啥的不必一样,VC下按ctrl+z 然后
    回车可结束程序):
    while(scanf("%d%d",&n,&q)!=EOF)
    {
        for(i=1;i<=q;i++)
        scanf("%d",&act[i]);
        ……
        ……
        printf("%d
",answer);
    }



 

来源

 sleepiforest 

 

作者

 a470086609

  如题主所说...水题一道,虽然标签是打着math的,但好像连规律都不需要怎么找;解这题的时候能被坑到的主要可能是一些情况没有考虑到:题目要求的是在最坏情况下,那就得想全面一点,让题中的让座次数尽可能的坏。。。╮(╯▽╰)╭

  我的解法是考虑到奇数和偶数的情况。先来看偶数情况下的一组例子:

input: 10 10

          1 2 3 4 5 6 7 8 9 10

output:7 6 5 4 3 3 4 5 6 7

首先从k==1开始,显而易见当你坐在最左边时如果在最右边的两个座位(9和10)填上人的话那么根据题目要求入座的人会选择途径人数最少的一边进入所以第四个人会在左边进入;因此最坏的情况就是9和10有人坐了后(这时让座次数还是0),而后的7个人从第8个位置一路坐过来(2←8)这种情况下坐k==1位置的就得让7次座 为最坏情况。   然后k==2到n/2的方法同理,且与n/2+1到n的结果是对称的。

  再看看奇数情况的一组例子:

input:  11 11

           1 2 3 4 5 6 7 8 9 10 11

output:8 7 6 5 4 3 4 5 6 7 8

讨论奇数时的最坏情况跟上面也是相同的但输入输出间对应的规律会有小不同;所以在上机码前在纸上多罗列几组数据,检验规律是否真确。

/* code */

#include <stdio.h>
#include <math.h>
void even(int n,int q);
void odd(int n,int q);
int main()
{
    int n,q,i;
    while(scanf("%d%d",&n,&q)!=EOF)
    {
        int a[q];
        for(i=0;i<q;i++)
            scanf("%d",&a[i]);

        if(n%2==0)
            for(i=0;i<q;i++)
                even(n,a[i]);
        else
            for(i=0;i<q;i++)
                odd(n,a[i]);
        putchar('
');
    }
    return 0;
}
void even(int n,int q)
{
    int middle=n/2;
    if(n==2)
        {
            printf("0 ");
            return;
        }
    if(q<=middle)
        printf("%d ",n-q-2);
    else
        printf("%d ",q-3);

}
void odd(int n,int q)
{
    int middle=n/2+1;
    if(n==1)
    {
        printf("0 ");
        return;
    }
    else if(n==3)
    {
        printf("%.lf ",fabs(middle-q));
        return;
    }
    printf("%.lf ",fabs(middle-q)+middle-3);
}