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

题意:5个人排队喝分身药水(一变二)在到排尾;

思路:进行一个简单的分析:

最初状态:A B C D E

所有人都喝一次之后的状态:AA BB CC DD EE

再一次:AAAA BBBB CCCC DDDD EEEE

....

把三个状态排在一行上,在分配一下区间(包含元素的个数),每个区间元素个数符合:第n区间 元素个数sum=2^(n-1)*5

       ABCDE  AABBCCDDEE  AAAABBBBCCCCDDDDEEEE
        [1,5](5)      [6,15](10)                  [16,35](20)

最后只要确定是那个区间谁喝的就可以了

代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 long long quick_pow(int n)//快速幂(可以直接求,不需要如此)
 5 {
 6     long long sum=1,b=2;
 7     while(n>0)
 8     {
 9         if(n%2)
10             sum*=b;
11         b=b*b;
12         n/=2;
13     }
14     return sum;
15 }
16 
17 int main()
18 {
19     int n,i,d,index=0;
20     long long mark[35][2],sum=0,a;//mark[i][0]记录第i区间的起始坐标,mark[i][1]记录截止坐标(一维数组也可以的)
21     for(i=0;i<=32;i++) //建立区间
22     {
23         mark[i][0]=sum+1;
24         sum+=quick_pow(i)*5;
25         mark[i][1]=sum;
26     }
27     cin>>n;
28     for(i=0;i<=32;i++) //确定区间位置
29     {
30         if(n>=mark[i][0]&&n<=mark[i][1])
31         {
32             index=i;break;
33         }            
34     }
35     a=(n-mark[index][0])/quick_pow(index);//确定是谁喝的
36     switch(a) 
37     {
38         case 0:cout<<"Sheldon"<<endl;break;
39         case 1:cout<<"Leonard"<<endl;break;
40         case 2:cout<<"Penny"<<endl;break;
41         case 3:cout<<"Rajesh"<<endl;break;
42         case 4:cout<<"Howard"<<endl;break;
43     }    
44 //    system("pause");
45     return 0;
46 }