hihocoder 1154 Spring Outing

传送门

#1154 : Spring Outing

时间限制:20000ms

单点时限:1000ms

内存限制:256MB

描述

You class are planning for a spring outing. N people are voting for a destination out of K candidate places.

The voting progress is below:

First the class vote for the first candidate place. If more than half of the class agreed on the place, the place is selected. The voting ends.

Otherwise they vote for the second candidate place. If more than half of the class agreed on the place, the place is selected. The voting ends.

Otherwise they vote for the third candidate place in the same way and go on.

If no place is selected at last there will be no spring outing and everybody stays at home.

Before the voting, the Chief Entertainment Officer did a survey, found out every one's preference which can be represented as a permutation of 0, 1, ... K. (0 is for staying at home.) For example, when K=3, preference "1, 0, 2, 3" means that the first place is his first choice, staying at home is the second choice, the second place is the third choice and the third place is the last choice.

The Chief Entertainment Officer sends the survey results to the class. So everybody knows the others' preferences. Everybody wants his more prefered place to be selected. And they are very smart, they always choose the optimal strategy in the voting progress to achieve his goal.

Can you predict which place will be selected?

输入

The first line contains two integers, N and K, the number of people in your class and the number of candidate places.

The next N lines each contain a permutation of 0~K, representing someone's preference.

For 40% of the data, 1 <= N, K <= 10

For 100% of the data, 1 <= N, K <= 1000

输出

Output the selected place. Or "otaku" without quotes if no place is selected.

样例提示

In the sample case, if the second peoson vote against the first place, no place would be selected finally because the first person must vote against the second place for his own interest. Considering staying at home is a worse choice than the first place, the second person's optimal strategy is voting for the first place. So the first place will be selected.

 

样例输入
2 2 1 0 2 2 1 0
样例输出
1

分析这道题出自微软2016校园招聘在线笔试第二场首先要明确题意这道题像是一道博弈论问题(有“纳什均衡的即视感”--某君语),并且确是一道博弈论问题。但没有博弈论的知识也可以入手分析。

 
  

我最初的思路也不是正解,赛后讨论区有人询问思路,答曰“倒推”。我想了一周左右,中间还和同学讨论了一次,才明白如何倒推(愚钝如我者)。

 
  

假设投票进行到了最后一轮(表决第K个也是最后一个地点)。此轮投票前,众人都知道(每个人都足够聪明)结果只有两种:去第K个地点 or 呆在家。此时,显然地,每个人都将投更想去的地方。将要进行第K轮投票时,大家已经知道最后结果了。因此事实上第K轮投票是没必要的。

 
  

假设第K轮投票结果是R(K),R(K)=0或K,那么第K-1轮投票的结果是K-1或R(K),或者说第K-1轮投票实际上是众人在第K-1和R(K)之间选择,因而结果R(K-1)也是预先知道的,第K-1轮投票也没必要。

 
  

按此思路可推知R(1),这就是答案。

 
  

我们看到在本题中,无需投票众人就知到最后结果了,当然这是由于投票前preference list已成为common knowledge,在实际中这往往是不可能的。

 
  

代码不难写,复杂度是O(N*K),已是读入复杂度了,也没有优化的必要。

 
  
#include<bits/stdc++.h>

#define X first

#define Y second

#define MP make_pair

using namespace std;

const int MAX_N=1e3+10, MAX_K=1e3+10;

int pref[MAX_N][MAX_K];

typedef pair<int, int> pii;

int N, K;

bool cmp(const int &x, const int &y){

    int a=x%(K+1), b=y%(K+1);

    int cnt1=0, cnt2=0;

    for(int i=0; i<N; i++){

        pref[i][a]<pref[i][b]?cnt1++:cnt2++;

    }

    return cnt1==cnt2?x>y:cnt1>cnt2;

}

int main(){

    //freopen("in", "r", stdin);

    int place;

    scanf("%d%d", &N, &K);

    for(int i=0; i<N; i++){

        for(int j=0; j<=K; j++){

            scanf("%d", &place);

            pref[i][place]=j;

        }

    }

    int last=K+1, pre=K;

    while(pre){

        if(cmp(last, pre)) --pre;

        else last=pre, --pre;

        //printf("%d %d\n", pre, last);

    }

    last==K+1?puts("otaku"):printf("%d\n", last);

    return 0;

}


                            

你可能感兴趣的:(spring)