Folding a Ribbon(思維)

問題 F: Folding a Ribbon

時間限制: 1 Sec  內存限制: 128 MB
提交: 11  解決: 9
[提交] [狀態] [討論版] [命題人:admin]

題目描述

Think of repetitively folding a very long and thin ribbon. First, the ribbon is spread out from left to right, then it is creased at its center, and one half of the ribbon is laid over the other. You can either fold it from the left to the right, picking up the left end of the ribbon and laying it over the right end, or from the right to the left, doing the same in the reverse direction. To fold the already folded ribbon, the whole layers of the ribbon are treated as one thicker ribbon, again from the left to the right or the reverse. 
After folding the ribbon a number of times, one of the layers of the ribbon is marked, and then the ribbon is completely unfolded restoring the original state. Many creases remain on the unfolded ribbon, and one certain part of the ribbon between two creases or a ribbon end should be found marked. Knowing which layer is marked and the position of the marked part when the ribbon is spread out, can you tell all the directions of the repeated folding, from the left or from the right? 
The figure below depicts the case of the first dataset of the sample input. 

 

輸入

The input consists of at most 100 datasets, each being a line containing three integers. 
n i j
The three integers mean the following: The ribbon is folded n times in a certain order; then, the i-th layer of the folded ribbon, counted from the top, is marked; when the ribbon is unfolded completely restoring the original state, the marked part is the j-th part of the ribbon separated by creases, counted from the left. Both i and j are one-based, that is, the topmost layer is the layer 1 and the leftmost part is numbered 1. These integers satisfy 1 ≤ n ≤ 60, 1 ≤ i ≤ 2n, and 1 ≤ j ≤ 2n. 
The end of the input is indicated by a line with three zeros. 

 

 

輸出

For each dataset, output one of the possible folding sequences that bring about the result specified in the dataset. 
The folding sequence should be given in one line consisting of n characters, each being either L or R. L means a folding from the left to the right, and R means from the right to the left. The folding operations are to be carried out in the order specified in the sequence. 

 

 

樣例輸入

3 3 2
12 578 2214
59 471605241352156968 431565444592236940
0 0 0

 

樣例輸出

LRR
RLLLRRRLRRLL
LRRRLRRLLRRRRLLLLRLLRRRLRRLLRLLLLLLRLRLLRLRLLLRLRLLRLLRRRLL

題目大意是說給你一張紙,每次向左或者向右折,告訴你折了N次以後從上向下數第i個在摺疊前是第j部分,求從第一次到第N次是分別是向左折還是向右折。

 

我的解法是先從後往前求每次摺疊以後第j個在從下向上數第cnt[i]個位置(如果cnt[i] < 厚度的一半,則cnt[i-1]=cnt[i];否則cnt[i-1]  = 厚度-cnt[i]+1,即是從下半部分摺疊上來的),求出所有的cnt[i]之後,再從前往後遍歷。因爲如果是把改點摺疊到另一半上面,則它的位置會上浮,否則保持不變,與此同時,我們更新這個點是當前從左往右數第幾個,即可知道當前點是在左半邊還是右半邊,再根據cnt[i]的變化即可得到摺疊方向。

 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100005;
ll poww[64];
ll cntt[100];
int cnt = 0;
int main()
{
//    freopen("in.txt", "r", stdin);
    ll n,m,k;
    poww[0] = 1;
    for (int i = 1; i <= 62; i++)
        poww[i] = poww[i - 1] << 1;
    while (~scanf("%lld%lld%lld",&n,&m,&k))
    {
        if (!n && !m && !k)
            break;
        m = cntt[n] = poww[n] - m + 1;
        for (cnt = n; cnt > 1; cnt--)
        {
            if (m > poww[cnt - 1])
                m = poww[cnt] - m + 1;
            cntt[cnt - 1] = m;
        }
        for (int i = 1; i <= n; i++)
        {
            if (k <= poww[n - i])
            {
                if (cntt[i] <= poww[i - 1])
                    printf("R");
                else
                {
                    printf("L");
                    k = poww[n - i] - k + 1;
                }
            }
            else
            {
                if (cntt[i] > poww[i - 1])
                {
                    printf("R");
                    k = poww[n - i + 1] - k + 1;
                }
                else
                {
                    printf("L");
                    k -= poww[n - i];
                }
            }
        }
        puts("");
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章