解题报告 之 SOJ2714 Mountains(II)

来源:互联网 发布:可以听pdf的软件 编辑:程序博客网 时间:2024/05/22 12:52

解题报告 之 SOJ2714 Mountains(II)



Description

A mountain consists of one or more hills, each of which consists of upwards, which we denote with `/', and downwards, which we denote with '\'. We call upwards and downwards together as wards. Let /n be an upward of length n, and in the same way, let \n be a downward of length n. For example, the following upward is /2:

 //

and the following downward is \3:

\ \  \

The set of all hills is given in the following:

Hills =def { /n\n | n is a natural number }

Now it comes to the definition of a mountain(in BNF):

Mountain ::= Hill | Mountain Mountain

That's to say, a hill is a mountain, and if M and N are mountains, then the concatenation of M and N is also a mountain.

For example,

     /\/\/\/  \

is a mountain with 3 hills.

We define the width of a mountain as the number of upwards and downwards. We define the height of a mountain as the maximum length of upwards(or equivalently downwards).

We can give each mountain a unique number, called index, such that the following conditions are met:

  1. index begins with 1
  2. the index of a mountain with larger width is larger
  3. if two mountains have the same width, then the index of the mountain whose leftmost different ward with the other mountain is an upward is larger

For example, portion of the mountains and their indices are:

                 /\                    /\                   /\         /\/\     /\/\     /  \     /\/\/\     /\/  \     ...     /\/\/  \     /\/  \/\     ...1       2        3         4          5                   9            10

In this problem, you are print the mountain from the given index.

Input

The input contains several lines, each of which contains an integer N<2^32. The last line contains 0, which you should not proceed.

Output

For each N, your program should print the mountain, and you need make the mountain climbing.

The output of two consecutive instances should be separated by a blank line.

Sample Input

690

Sample Output

 /\/  \/\     /\/\/\/  \

Author: fgjlwj


题目大意:每条山脉都由一些山头构成,且每座山脉有一个排名,如果一座山宽度比较小或者宽度一样大但字典序小(即山包的宽度字典序),那么它的排名就更靠前。问你排名第n的山脉长什么样子?

分析:这个题是 SOJ1678 的升级版题目都是一样的只是此题输出稍微复杂一点,对原理有兴趣的请参考另一篇博文 SOJ1678 题解。
那么这个题输出怎么搞的,我是分层输出的,扫描每一层,如果某山包高度够了,那么就输出对应层次的字符(空格 - / - 空格 - \ - 空格),如果不够就输出num[j]*2的空格。

那么直接上代码吧,需要题目原理的就看看SOJ1678.
#include<iostream>#include<algorithm>#include<string>#include<cmath>using namespace std;int num[50];long long q_pow( long long a, long long b ){    long long ans = 1;    while(b)    {        if(b & 1)        {            ans *= a;        }        b /= 2;        a *= a;    }    return ans;}int main(){    long long n;    while(cin >> n&&n)    {        int w = log2( n )+1;        long long loc =n - (q_pow( 2, w - 1 ) - 1);        int h = 1;        int cnt = 1;        int digit = 1;        long long l = 1, r = q_pow( 2, w - 1 );        while(l < r)        {            long long mid = (l + r) / 2;            if(loc <= mid)            {                num[cnt++] = digit;                h = max( h, digit );                digit = 1;                r = mid ;            }            else            {                digit++;                l = mid + 1;            }        }        num[cnt] = digit;        h = max( h, digit );        for(int i = h; i >=1; i--)        {            for(int j = 1; j <= cnt; j++)            {                if(num[j] >= i)                {                    int width = (num[j] - i+1) * 2;                    cout << string( num[j] - width / 2, ' ' );                    cout << "/" << string( width - 2 , ' ' ) << "\\";                    cout << string( num[j] - width / 2, ' ' );                }                else                    cout << string( 2 * num[j], ' ' );            }            cout << endl;        }        cout << endl;    }    return 0;}

See You Next Illusion!

0 0