题目链接:http://codeforces.com/problemset/problem/82/A

 

这道题一开始我拿到的时候,第一反应就是这道题是一道找规律的模拟题

但是我进入了一个误区:那就是我在想:如果是使某一人拿到可乐的n之间存在某种特殊的联系

然后我就进入这个坑里面再也出不来了

 

后来在网上看了很多题解,但是他们大概的思想我可以理解,但是就是他们的实现过程我可以说我完全看不懂大佬们的思想吗?!

 

这道题目的思想其实很简单: 

队伍的变换:

abcde -> aabbccddee -> aaaabbbcccdddeee -> aaaaaaaabbbbbbbbccccccccddddddddeeeeeeee ...

单个人的人数变化:1 -> 2-> 4 -> 8 ...(each_cnt每次都*2)

队伍总人数变化:5个 -> 10个 -> 20个 -> 40个(sum也是每次都*2)

1、首先是确定给的n是在第几组的范围内

比如: n=8  这个n是在第二组的范围

2、我们要确定这个数是在第几组的编号是多少 (每组我们都进行重新的编号 例如: n=8  它在第二组的编号是3)

3、因为每组的单个人的人数(each_cnt)其实是不同的,所以我们可以根据each_cnt来确定到底是谁喝到饮料

 

这道题的难点我觉得就是在第三步:


首先我们要看 n%each_cnt =? 0 

为什么呢?

因为n % each_cnt == 0 和 n % each_cnt != 0  所遵循的计算的公式是不一样的

具体的还是手动模拟一下就可以知道了

 

AC代码:

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
char nm[10][10] = {"Sheldon", "Leonard", "Penny", "Rajesh", "Howard" };
int main()
{
    int n,sum = 5,each_cnt = 1,res;
    scanf("%d",&n);
    while(n > sum)  // 确定在第几组的编号
    {
        n -= sum;
        each_cnt *= 2;
        sum *= 2;
    }
    if(n % each_cnt == 0)   res = n / each_cnt;
    else    res = n / each_cnt + 1;
    switch(res)
    {
        case 1:puts(nm[0]);break;
        case 2:puts(nm[1]);break;
        case 3:puts(nm[2]);break;
        case 4:puts(nm[3]);break;
        case 5:puts(nm[4]);break;
    }
    return 0;
}