题目链接: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; }