HDU 1443解题报告

来源:互联网 发布:张予曦真人好看吗 知乎 编辑:程序博客网 时间:2024/04/29 15:45

Joseph

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1768    Accepted Submission(s): 1095


Problem Description
The Joseph's problem is notoriously known. For those who are not familiar with the original problem: from among n people, numbered 1, 2, . . ., n, standing in circle every mth is going to be executed and only the life of the last remaining person will be saved. Joseph was smart enough to choose the position of the last remaining person, thus saving his life to give us the message about the incident. For example when n = 6 and m = 5 then the people will be executed in the order 5, 4, 6, 2, 3 and 1 will be saved.

Suppose that there are k good guys and k bad guys. In the circle the first k are good guys and the last k bad guys. You have to determine such minimal m that all the bad guys will be executed before the first good guy. 
 

Input
The input file consists of separate lines containing k. The last line in the input file contains 0. You can suppose that 0 < k < 14. 
 

Output
The output file will consist of separate lines containing m corresponding to k in the input file. 
 

Sample Input
340
 

Sample Output
530
 

Source
ACM暑期集训队练习赛(5)
 

Recommend
lcy

       这道题属于一道比较经典的模拟题。但是如果方法选用不当,模拟的复杂度太高的话会导致TLE。。因此我们需要格外注意,降低模拟的复杂度。利用好取模的性质进行模拟。假设j是要数到的编号,那么假设数到j这个数的人位置为t,这个人被杀以后,我们需要进行的操作是将这个人后边一直到末尾的编号都减1,相当于补充被杀的这个人的位置缺口。这时我们计算下一个被杀的人的位置。就是(t+j-1)%num(num表示总人数,这时的num是减去1之后的,因为杀掉一个人num就要减1)。这个式子得出的位置结果就是下一个要被杀的人的位置。这个式子很巧妙。t是被杀的人的位置,而我们需要做的是将被杀的那个人之后的所有人的编号都减小1,那么原先的(t+1)位置的人现在编号为t,(t+2)位置的人现在为(t+1),所以把当前的t位置当为起始位置,以后的标号就为0,1,2,3……j-1,总共j个人。所以用(t+j-1)%num就是下一个被杀人的位置。因而要掌握好这个式子表示的含义,也就能很方便的理解约瑟夫环的过程。这个式子比其他的模拟过程要简洁的多,也可以较快的求出结果。 

      参考代码:

#include<cstdio>int a[15];int main(){    int n;    for(int i=1;i<=14;i++)    {        for(int j=i+1;;j++)        {            int num=2*i,t=j%num;  //num表示总人数,t表示被杀人的位置            if(t==0) t=num;            int cnt=0;            while(t>i)  //因为要保证i+1~2*i的人先被杀,所以被杀人的编号t要始终大于i,如果不大于i,则退出循环,那么被杀的人的个数也就达不到i            {                num--;                t=(t+j-1)%num;                if(t==0) t=num;                cnt++;             //cnt表示被杀的人的个数            }            if(cnt==i)            {                a[i]=j;                break;            }        }    }    while(~scanf("%d",&n)&&n)    {        printf("%d\n",a[n]);    }}

0 0
原创粉丝点击