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:
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.
The input contains several lines, each of which contains an integer N<2^32. The last line contains 0, which you should not proceed.
For each N, your program should print the mountain. For simplicity, you needn‘t make the mountain climbing. You can imagine that the mountain finally printed is the one after being flattened. For example, for N=9, your program should simply print:
/\/\//\\
.
Each mountain should be printed in a single line.
6 9 0
//\\//\/\//\\
Problem Source: siyee
#include<iostream> #include<algorithm> #include<string> #include<cmath> using namespace std; int num[50]; long long q_pow( long long a, long long b ) //快速幂 计算a^b,直接用pow感觉也行 { 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)//很容易发现前一半的解都是以digit为当前位的 { num[cnt++] = digit; digit = 1; r = mid; } else //后一半的解的最小的数位为digit+1,后面接着二分 { digit++; l = mid + 1; } } num[cnt] = digit; for(int j = 1; j <= cnt; j++) { cout << string( num[j], '/' ) << string( num[j], '\\' ); } cout << endl; } return 0; }
原文地址:http://blog.csdn.net/maxichu/article/details/45592037