华师一附中OI组

标题: P1338 末日的传说 [打印本页]

作者: 倚窗倾听风吹雨    时间: 2018-9-23 21:34
标题: P1338 末日的传说
https://www.luogu.org/problemnew/show/P1338

题目描述
只要是参加jsoi活动的同学一定都听说过Hanoi塔的传说:三根柱子上的金片每天被移动一次,当所有的金片都被移完之后,世界末日也就随之降临了。

在古老东方的幻想乡,人们都采用一种奇特的方式记录日期:他们用一些特殊的符号来表示从1开始的连续整数,1表示最小而N表示最大。创世纪的第一天,日历就被赋予了生命,它自动地开始计数,就像排列不断地增加。

我们用1-N来表示日历的元素,第一天日历就是

1, 2, 3, … N

第二天,日历自动变为

1, 2, 3, … N, N-1

……每次它都生成一个以前未出现过的“最小”的排列——把它转为N+1进制后数的数值最小。

日子一天一天地过着。有一天,一位预言者出现了——他预言道,当这个日历到达某个上帝安排的时刻,这个世界就会崩溃……他还预言到,假如某一个日期的逆序达到一个值M的时候,世界末日就要降临。

什么是逆序?日历中的两个不同符号,假如排在前面的那个比排在后面的那个更大,就是一个逆序,一个日期的逆序总数达到M后,末日就要降临,人们都期待一个贤者,能够预见那一天,到底将在什么时候到来?

输入输出格式
输入格式:
只包含一行两个正整数,分别为N和M。

输出格式:
输出一行,为世界末日的日期,每个数字之间用一个空格隔开。

输入输出样例
输入样例#1:
5 4
输出样例#1:
1 3 5 4 2
说明
对于10%的数据有N <= 10。

对于40%的数据有N <= 1000。

对于100%的数据有 N <= 50000。

所有数据均有解。
作者: 倚窗倾听风吹雨    时间: 2018-9-23 21:34
  1. #include<iostream>
  2. #include<algorithm>
  3. #define FOR(i,a,b) for(int i=a;i<=b;i++)
  4. using namespace std;
  5. long long int n,m;
  6. int a[50010];
  7. int main()
  8. {
  9.     cin>>n>>m;
  10.     long long int la=n;
  11.     long long int fi=1;
  12.     FOR(i,1,n)
  13.     {
  14.         long long int t=(long long int)(n-i)*(n-i-1)/2;
  15.         if(t>=m)a[fi++]=i;
  16.         else
  17.         {
  18.             a[la--]=i;
  19.             m=m-(la-fi+1);
  20.         }
  21.     }
  22.     FOR(i,1,n)cout<<a[i]<<" ";
  23.     cout<<endl;
  24.     return 0;
  25. }
复制代码





欢迎光临 华师一附中OI组 (http://hsyit.cn/) Powered by Discuz! X3.2