Sicily 2012. King

明确最重要的一点:每个小孩间都存在胜负关系,非胜则负。而小孩王的条件是该小孩不惧怕任何其他的小孩,即其打败的小孩(直接打败)加上他打败的小孩打败了的小孩(间接打败)之和等于其他小孩的总数。
就以上而言,题目是比较简单的,只需要对每个孩子都进行二步深搜即可,但这样会超时。关键在于找到个中的规律。
如果至少存在一个小孩王,可以假设出度(直接打败其他小孩的人数)最大的那个小孩是小孩王之一。对于这个假设,用反证法证明:假设出度最大的那个(用A表示)不是小孩王,就表示A直接打败了的n个人中,没有人能打败B,而B又打败了A,这样A就惧怕B,故A不是小孩王。上面的论述中,明显可以发现B打败了A打败了的n个人并且打败了A,那么B的出度就是n+1,比A的n大,则A不是出度最大的那个,与前提矛盾,可知假设成立。所以,只要寻找这个小孩并输出即可。
如果不存在小孩王,仍然按照上述假设,若A不是小孩王,则存在出度比A大的B,若B还不是,则存在出度比B还大的C,如果这种情况一直存在,则依次类推直至最后一个小孩,若此小孩不是小孩王,则存在出度比这个小孩还大的,但由上面的推断可知最后一个小孩的出度是最大的,不可能存在出度还要大的情况;故此小孩一定是是小孩王,这样就与题设矛盾了。以此反证,可知必定存在至少一个小孩王。
综上而言,直接找出出度最大的那个小孩就是最后的答案。

Run Time: 0.04sec

Run Memory: 304KB

Code length: 593Bytes

SubmitTime: 2011-12-07 23:57:07

// Problem#: 2012
// Submission#: 1049697
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <cstdio>
#include <cstring>
using namespace std;

int main()
{
    int n;
    int i, j, k;
    char s[ 1000 ];
    int out, max, king;

    while ( scanf( "%d", &n ) != EOF ) {
        king = 0;
        max = 0;
        for ( i = 0; i < n; i++ ) {
            out = 0;
            scanf( "%s", s );
            for ( j = 0; j < n; j++ ) {
                if ( s[ j ] == '1' )
                    out++;
            }
            if ( out > max ) {
                king = i;
                max = out;
            }
        }
        printf( "%d\n", king + 1 );
    }

    return 0;

}                                 


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值