uva 10940 Throwing cards away II

原题:
Given is an ordered deck of n cards numbered 1 to n with card 1 at the top and card n at the bottom. The following operation is performed as long as there are at least two cards in the deck: Throw away the top card and move the card that is now on the top
of the deck to the bottom of the deck. Your task is to find the last, remaining card.
Input
Each line of input (except the last) contains a positive number n≤ 500000. The last line contains ‘0’ and this line should not be processed. Input will not contain more than 500000 lines.
Output
For each number from input produce one line of output giving the last remaining card.
Sample Input
7
19
10
6
0
Sample Output
6
6
4
4

中文:
给你n个牌摞成一堆,每次把第一张扔掉,然后再把第一张放到最后,输出最后剩下的牌。

#include 
using namespace std;
int f[500001];
int main()
{
    ios::sync_with_stdio(false);
    f[1]=1;
    for(int i=2;i<=500000;i++)
    {
        if(i%2==0)
            f[i]=2*f[i/2];
        else
            f[i]=2*f[(i+1)/2]-2;
    }
    int n;
    while(cin>>n,n)
    cout<return 0;
}

思路:
和10935一个意思,只不过数据量大,需要用数学方法解决。类似于约瑟夫环的问题(LA3882)的数学解法。
考虑地推的形式
当n为偶数时,第一次会把偶数下标的数都删掉,操作后的数依然是从小到大且从第一个开始删除,所以当n为偶数时,f(n)=2*f(n/2)
例如
n=6时,起始序列为1 2 3 4 5 6,删除第一趟后为2 4 6,且下次再删除从2开始,相当于n=3时的结果再乘以2。
当n为奇数时,第一次删除后,得到的序列是把第一个数放到最后,从第2个数开始各一个一删除,此时可以在删除第一趟后的数的最上端补上一个0,那么就变成从头删除,所以当n为奇数时f(n)=2*f((n+1)/2)-2

例如当n=7时,初始序列1 2 3 4 5 6 7,删除第一趟后为2 4 6,且下一次再操作时是把2放到最后,删除4,那么在前面补个0后变成0 2 4 6对应1 2 3 4相当对应2*n-2

你可能感兴趣的:(数学)