nyist14年3月月赛题解

比赛链接:

http://acm.bnu.edu.cn/bnuoj/contest_show.php?cid=3475#info

比较没状态,成绩不算好。题目有很水,都是靠脑子的。

旅游

1000ms
65536KB
64-bit integer IO format:  %lld      Java class name:  Main
Font Size:   
Type: 
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •                    
  •  

    某L是一个旅游爱好者,并且伴有轻微强迫症。不管去什么地方旅游,他总是要走遍每一个景点,以求不留遗憾。

     前段时间,他又去了一个名叫YNBHX的景区,这个景区非常特别,它一共有N个景点和N-1条小道,每条小道连接这N个景点中的某两个,并保证从景区内每一个景点都能通过若干条小道到达另一个景点。

    由于景区人数微多,景区规定,每人每天可以选择任意一个景点出发到达另一个景点,但途中不能走回头路(即每一条小道在同一天之内只能经过一次),现在某L想知道,对于这个神奇的景区,他要想游览完所有的景区至少需要几天?=,=

    Input

     

    第一行一个整数N,表示共有N个景点。(N<=1000)

    接下来N-1行,每行两个整数A、B,表示景点A和景点B之间有一条小道。

    Output

    一个整数K,表示某L要想游览完所有景点至少需要K天。

    Sample Input

    Sample Input1
    3
    1 2
    2 3
    
    Sample Input2
    4
    1 2
    1 3
    1 4
    

    Sample Output

    Sample Output1
    1
    
    Sample Output2
    2
    

    水题:只用判断无向图的度,度大于2的把大于2的部分加起来,最后ans=(sum+1)/2+1;

    #include <cstdio>
    #include <cstring>
    int in[2000],out[2000];
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            int x,y;
            memset(in,0,sizeof(in));
            memset(out,0,sizeof(out));
            for(int i=1;i<n;i++)
            {
                scanf("%d%d",&x,&y);
                in[x]++;in[y]++;
            }
            int ans=0;
            for(int i=0;i<1001;i++)
            {
                if(in[i]>2)
                {
                    ans+=(in[i]-2);
                }
            }
            printf("%d\n",(ans+1)/2+1);
        }
        return 0;
    }

    C题,简单的贪心

    选机房

    1000ms
    65535KB
    64-bit integer IO format:  %lld      Java class name:  Main
    Font Size:   
    Type: 
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •                    
  • BNU程序设计大赛就要开始了,决赛地点暂时定在电子楼,因为电子楼有很多各种大小的机房,目前估计参赛的队伍总数为n,但是学校可能没有那么大的机房容纳所有队伍,可能要将选手分配在几个小机房中进行比赛,xyjian老大安排你去选机房,为了让比赛选手相对集中,要求选中机房的总数最少,另外在满足这一前提的情况下尽可能选择较大的机房。现在你得到了BNU所有机房的能容纳队伍数目的情况表,请你编程自动选择机房。

    Input

    输入文件包含多组数据。
    文件第一行:一个正整数t<=20表示测试数据的组数。
    接下来t行表示t组数据,每组数据按照以下格式:
    第一行两个正整数n<=100000和k<=1000以空格隔开,表示参赛队的总数和可以选择的机房总数k。
    接下来k行每行一个正整数c<=20000。
    第1行表示1号机房所能容纳的队伍总数,第2行表示2号机房能容纳的队伍数,以此类推,已知所有k个机房的大小均不相同,并且所有机房的总容量大于n。

    Output

    对每组数据输出所要选择的机房的编号,每个编号一行,从小到大输出,每组数据后请输出一个空行。

    Sample Input

    2
    200 2
    300
    400
    100 5
    50
    4
    20
    40
    5
    
    

    Sample Output

    2
    
    1
    3
    4
    
    

    Source

    无任何掺杂,纯水题:

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    struct Node
    {
        int sum;
        int num;
    };
    Node a[2000];
    int comp(Node x,Node y)
    {
        if(x.sum!=y.sum)
            return x.sum>y.sum;
    }
    int main()
    {
        int n,k,T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&k);
            for(int i=1;i<=k;i++)
            {
                scanf("%d",&a[i].sum);
                a[i].num=i;
            }
            sort(a+1,a+k+1,comp);
            int ans[2000],cas=0,count=0;
            for(int i=1;i<=k;i++)
            {
                count+=a[i].sum;
                if(count<n)
                {
                    ans[cas++]=a[i].num;
                }
                //else if(count==n)
                  //  break;
                else{
                    ans[cas++]=a[i].num;break;
                }
            }
            sort(ans,ans+cas);
            for(int i=0;i<cas;i++)
                printf("%d\n",ans[i]);
            printf("\n");
        }
        return 0;
    }

    E题,靠思想,考的时候想到了,但是想错了。

    Liar Game 少数决游戏

    1000ms
    65536KB
    64-bit integer IO format:  %lld      Java class name:  Main
    Font Size:   
    Type: 
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •                    
  •        大钰儿最近看了一部日剧《Liar Game》,非常喜欢里面的一个游戏,叫少数决游戏。游戏的规则很简单,有N个人进行投票,选项为Yes和No,每个人投且仅投一票。选择了得票数较少的一项的游戏者晋级下一轮,如果Yes和No得票相同,或者大家都投了相同的票,则重新投一次。如此投票直到剩下1个人或者2个人为止。这时,剩下的人就获得了游戏的胜利。

           比如,有7个人投票,编号为1到7。其中1,3,6,7选择了Yes,2,4,5选择了No。那么2,4,5便可以进入下一轮(因为No的得票比Yes少,投票给No的人晋级下一轮)。在第二轮中,2投了Yes,4,5投了No,那么2就是最后的胜利者(Yes的得票比No少,只有2号投了Yes)。

           假设参加游戏的N个人里面有一个你的小团体,你可以安排他们的投票,并假设其他人都是随机投票的。只要最终剩下的1个或者2个人都属于这个小团体,那么你就获胜了。

           现在问题来了,这个小团体至少需要多少人才能保证你的胜利呢?

    Input

    输入有多组数据(数据不超过10000组),以EOF结尾。

    每组数据占一行,只包含一个整数N(1<=N<= 1,000,000,000),代表参加游戏者的数量。

    Output

    对每组数据,输出一个整数,代表为了保证小团体获胜,至少需要的人数。

    Sample Input

    3
    4
    8
    

    Sample Output

    2
    2
    4
    

    Hint

    比如3个人进行投票,你的小团体有2个人,你让他们一个投Yes,一个投No,那么无论第3个人投什么票都会被淘汰。最终剩下的肯定是小团体中的一员,所以你肯定能获胜。但3个人中小团体只有一个人,显然就不能保证胜利了。所以,如果游戏者总共有3个人的话,小团体至少要2个人才能保证你的胜利。当游戏者有4个人,小团体还是2个人,你还是安排一个人投Yes,一个人投No。由于剩下的两个人是随机投票,总会有一次他们投的是一样的票,那么最后剩下的肯定就是小团体中的一个了。这种情况下,我们认为小团体还是会获得游戏的胜利。

    递归的运用,奇数的时候是2*ans/2,偶数2*(ans-1)/2

    #include <cstdio>
    int search(int x)
    {
        if(x==1)
            return 1;
        if(x==2)
            return 2;
        if(x%2)
            return search(x/2)*2;
        else
            return search(x/2-1)*2;
    }
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            printf("%d\n",search(n));
        }
        return 0;
    }
    

    F题:

    起床的烦恼

    2000ms
    65536KB
    64-bit integer IO format:  %lld      Java class name:  Main
    Font Size:   
    Type: 
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •                    
  • 众所周知,nono是一只喜欢睡懒觉的熊猫。“我曾经也是早睡早起,直到我膝盖中了一箭”,nono如是解释道。现在nono又遇到了一个难题:他睡醒了…但是显然,nono并不想起床……于是他决定用如下方法来解决这个问题。
    Nono从一开始数数,他每数一个数时会计算这个数中1的个数(如211中有两个1)并对1的个数进行累和,当1的个数之和不小于x时,nono就要起床了。特别需要注意的是,当nono数数达到10000时,nono就会因为数太久而再次睡着……
    现在nono定下了x,他想知道他数到多少就需要起床了(或是他可以再睡一觉)。

    Input

    第一行为一个整数T(T<=5000)表示数据组数,接下来的T行每行一个整数x(0<x<30000)。

    Output

    对于每组数据,如果nono会数到睡着则输出"zzz",否则输出一个数表示nono需要数到多少。

    Sample Input

    2
    1
    2
    

    Sample Output

    1
    10
    

    递推:

    #include <cstdio>
    int a[100000];
    void isit()
    {
        int cas=1;
        int i;
        for(i=1;i<=100000;i++)
        {
            int k=i,sum=0;
            while(k)
            {
                if(k%10==1){
                    sum++;
                    a[cas++]=i;
                }
                k/=10;
            }
            a[i]=a[i-1]+sum;
        }
    }
    int main()
    {
        isit();
        int T;
        scanf("%d",&T);
        while(T--)
        {
            int n,ans=0,ok=1;
            scanf("%d",&n);
            if(a[n]<10000)
                printf("%d\n",a[n]);
            else
                printf("zzz\n");
        }
        return 0;
    }

    B题:
    一上来就坐这个题目,但是知道结束还没有对。没有明白期望是什么东西。

    旋转方块

    1000ms
    65535KB
    64-bit integer IO format:  %lld      Java class name:  Main
    Font Size:   
    有一种电脑赌博的游戏,电脑先生成两个8*8的图案块(只含有'.','*','#'),如下图

    方块1:       方块2:
    ........     ..*.....
    ...*...*     ...*...*
    ....*...     .*..*#.*
    ....#.#.     .*#.*...
    ....#...     .*..*...
    .#..*...     .*..*...
    ...*..#.     ...#..#.
    ....#...     ...#..#.

    当你按键开始游戏的之后,电脑随机的多次转动两个方形块(向右90度旋转);
    例如将方块1旋转2次,方块2旋转3次后方块变为如下图形。

    方块1:       方块2:
    ...#....     .**.....
    .#..*...     ......##
    ...*..#.     ..#.....
    ...#....     ..****..
    .#.#....     .*....##
    ...*....     *..#....
    *...*...     ..****..
    ........     ........

    电脑之后会将两个方形图案重叠起来。
    如果两个'.'重合在一起你可以得到1分,
    如果两个'*'重合在一起你可以得到2分,
    如果两个'#'重合在一起你可以得到3分。
    现在给你初始的两个8*8的方形块请你算出你得分的期望。

    Input

    输入数据共16行,前8行描述了方块1,后8行描述了方块2。

    Output

    输出一行:你的得分的期望值(四舍五入到小数点后两位)。

    Sample Input

    ........
    ...*...*
    ....*...
    ....#.#.
    ....#...
    .#..*...
    ...*..#.
    ....#...
    ..*.....
    ...*...*
    .*..*#.*
    .*#.*...
    .*..*...
    .*..*...
    ...#..#.
    ...#..#.

    Sample Output

    43.00

    原来这里期望可以理解为一个平均数,所有情况和sum/16即可。真是头大了。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    char Map1[11][11], Map2[11][11];
    int flag[11][11];
    void fun1()
    {
        memset(flag, 0, sizeof(flag));
        for(int i = 1; i <= 8; i++)
        {
            for(int j = 1; j <= 8; j++)
            {
                if(!flag[i][j])
                {
                    char ch = Map1[i][j];
                    Map1[i][j] = Map1[j][8-i+1];
                    Map1[j][8-i+1] = ch;
                    flag[i][j] = 1;
                    flag[j][8-i+1] = 1;
                }
    
            }
        }
    }
    void fun2()
    {
        memset(flag, 0, sizeof(flag));
        for(int i = 1; i <= 8; i++)
        {
            for(int j = 1; j <= 8; j++)
            {
                if(!flag[i][j])
                {
                    char ch = Map2[i][j];
                    Map2[i][j] = Map2[j][8-i+1];
                    Map2[j][8-i+1] = ch;
                    flag[i][j] = 1;
                    flag[j][8-i+1] = 1;
                }
            }
        }
    }
    int add()
    {
        int sum = 0;
        for(int i = 1; i <= 8; i++)
            for(int j = 1; j <= 8; j++)
            {
                if(Map1[i][j] == Map2[i][j])
                {
                    if(Map1[i][j] == '.')
                        sum += 1;
                    else if(Map1[i][j] == '*')
                        sum += 2;
                    else if(Map1[i][j] == '#')
                        sum += 3;
                }
            }
        return sum;
    }
    int main()
    {
        int i, j;
        for(i = 1; i <= 8; i++)
            for(j = 1; j <= 8; j++)
                cin >> Map1[i][j];
        for(i = 1; i <= 8; i++)
            for(j = 1; j <= 8; j++)
                cin >> Map2[i][j];
        int ans = 0;
        for(i = 0; i < 4; i++)
        {
            fun1();
            for(j = 0; j < 4; j++)
            {
                fun2();
                ans += add();
            }
        }
        printf("%.2lf\n",ans*1.0/16);
        return 0;
    }


    • 0
      点赞
    • 0
      收藏
      觉得还不错? 一键收藏
    • 0
      评论

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值