P1338 末日的传说
题目描述
只要是参加 jsoi 活动的同学一定都听说过 Hanoi 塔的传说:三根柱子上的金片每天被移动一次,当所有的金片都被移完之后,世界末日也就随之降临了。
在古老东方的幻想乡,人们都采用一种奇特的方式记录日期:他们用一些特殊的符号来表示从 1 1 1 开始的连续整数, 1 1 1 表示最小而 n n n 表示最大。创世纪的第一天,日历就被赋予了生命,它自动地开始计数,就像排列不断地增加。
我们用
1
−
n
1-n
1−n 来表示日历的元素,第一天日历就是:
1
,
2
,
…
,
n
−
2
,
n
−
1
,
n
1,2,\ldots,n-2,n-1,n
1,2,…,n−2,n−1,n
第二天,日历自动变为
1
,
2
,
…
,
n
−
2
,
n
,
n
−
1
1,2,\ldots,n-2,n,n-1
1,2,…,n−2,n,n−1
······每次它都生成一个以前未出现过的“最小”的排列——把它转为
n
+
1
n+1
n+1 进制后数的数值最小。
日子一天一天地过着。有一天,一位预言者出现了——他预言道,当这个日历到达某个上帝安排的时刻,这个世界就会崩溃······他还预言到,假如某一个日期的逆序达到一个值 m m m 的时候,世界末日就要降临。
什么是逆序?日历中的两个不同符号,假如排在前面的那个比排在后面的那个更大,就是一个逆序,一个日期的逆序总数达到 m m m 后,末日就要降临,人们都期待一个贤者,能够预见那一天到底将在什么时候到来?
输入格式
只包含一行两个正整数,分别为 n n n 和 m m m。
输出格式
输出一行,为世界末日的日期,每个数字之间用一个空格隔开。
输入输出样例 #1
输入 #1
5 4
输出 #1
1 3 5 4 2
说明/提示
对于 10 % 10\% 10% 的数据有 n ≤ 10 n\le10 n≤10;
对于 40 % 40\% 40% 的数据有 n ≤ 1000 n\le1000 n≤1000;
对于 100 % 100\% 100% 的数据有 n ≤ 5 × 1 0 4 n\le5\times10^4 n≤5×104。
所有数据均有解。
C++实现
#include
#include
using namespace std;
long long n,m,s,now;
vector v;
int main(){
scanf(“%lld %lld”,&n,&m);
for(int i=1;i<=n;i++) v.push_back(i);
s=(n*(n-1))>>1;
for(int i=n-1;i>=0;i–){
s-=i;
if(m>s){
now=m-s;
m=s;
}else now=0;
printf("%d ",v[now]);
v.erase(v.begin()+now);
}
return 0;
}
后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容