题目描述

Byteasar bought his son Bytie a set of blocks numbered from to and arranged them in a row in a certain order. Bytie's goal is to rearrange the blocks so that they are ordered naturally, from the smallest number to the largest. However, the only moves Bytie is allowed to make are: putting the last block at the very beginning (move a), and putting the third block at the very beginning (move b). Help Bytie by writing a program that tells whether a given arrangement of blocks can be properly reordered, and tells the right sequence of moves if it is.

有一个1..n的排列,有两种操作:
(a) 将最后一个数移到最前面
(b) 把第三个数移到最前面

我们将连续进行k次同一个操作称为“一块操作”,表示为ka或kb。
找到一个操作序列使得进行这些操作后,排列变为1,2,3,...,n。

输入

In the first line of the standard input there is a single integer ,(1<=N<=2000). In the second line there are integers from the range to , separated by single spaces. No number appears twice, and thus they represent the initial arrangement of the blocks. .

第一行n(1<=n<=2000)
下面一行n个数表示这个排列。

输出

如果不存在这样的操作序列,输出"NIE DA SIE",否则
第一行m,表示操作的块数。
下面一行,表示这m块操作。
需要满足相邻两块操作的种类不同,每块操作中进行的次数大于0小于n。
需要满足m<=n*n

样例输入

Sample Input #1
4
1 3 2 4
Sample Output #1
4
3a 2b 2a 2b

Sample Input #2
7
1 3 2 4 5 6 7
Sample Output #2
NIE DA SIE

Sample Input #3
3
1 2 3
Sample Output #3
0

 
  虽然是一道模拟题,但思维含量还是很大的。首先,为了让序列有序,我们一定是一个一个使他们变得有序,也就是在1-i有序后使i+1排在i的后面。假设现在1~i-1已经有序了,那么就要先把i挪到到第一位,然后使这时的1~i-1在最后,这样再把1~i-1挪到最前面就使1~i有序了。但当i在最前面时,1~i-1后面会还有一些数,这时我们只要两次a一次b就可以把最后两个挪到i的后面且使i还在第一个。但这样挪完后面可能还剩一个,这时只要一次a两次b就好了。但当按上述操作进行到最后时n和n-1可能是反的,这时把n-1挪到第一个,但不能依靠上面的操作再进行了。我们可以进行两次b操作来使n-1往后挪两位,再将n-1及后面数依次挪到第一个,重复上述操作,如果n是偶数这样做就可以把序列变得有序,如果n是奇数就只能无解了。
#include<map>
#include<set>
#include<queue>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n;
int now;
int tot;
int f[2010];
int a[2010];
int p[2010];
int c[4000010];
bool vis[4000010];
int pos(int x)
{
return (now+p[x]-1)%n+1;
}
int get(int x)
{
return ((x-now-1)%n+n)%n+1;
}
void make1(int x)
{
x%=n;
if(!x)
{
return ;
}
now+=x;
c[++tot]=x;
vis[tot]=0;
}
void make2()
{
int s1=get(1);
int s2=get(2);
int s3=get(3);
int x=f[s1];
int y=f[s2];
int z=f[s3];
int t=p[x];
p[x]=p[y];
p[y]=p[z];
p[z]=t;
f[p[x]]=x;
f[p[y]]=y;
f[p[z]]=z;
c[++tot]=1;
vis[tot]=1;
}
void print()
{
int ans=0;
for(int i=1;i<=tot;i++)
{
if(i==1||vis[i]!=vis[ans])
{
ans++;
vis[ans]=vis[i];
c[ans]=c[i];
}
else
{
c[ans]+=c[i];
}
}
tot=ans;
ans=0;
for(int i=1;i<=tot;i++)
{
if(vis[i]==0)
{
c[i]%=n;
}
else
{
c[i]%=3;
}
if(c[i])
{
c[++ans]=c[i];
vis[ans]=vis[i];
}
}
printf("%d\n",ans);
int i;
for(i=1;i<ans;i++)
{
if(vis[i]==0)
{
printf("%da ",c[i]);
}
else
{
printf("%db ",c[i]);
}
}
if(ans)
{
if(vis[i]==0)
{
printf("%da\n",c[i]);
}
else
{
printf("%db\n",c[i]);
}
}
}
int main()
{
scanf("%d",&n);
if(n==1)
{
printf("0\n");
return 0;
}
if(n==2)
{
scanf("%d%d",&a[1],&a[2]);
if(a[1]==1)
{
printf("0\n");
return 0;
}
else
{
printf("1\n1a\n");
return 0;
}
}
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
p[a[i]]=i;
f[i]=a[i];
}
for(int i=2;i<=n-2;i++)
{
int x=pos(i);
make1(n-x+1);
int t=n-pos(i-1);
while(t>1)
{
t-=2;
make1(2);
make2();
}
if(t)
{
make1(1);
make2();
make2();
}
}
if(n==3)
{
make1(n-pos(1)+1);
}
if(f[get(2)]<f[get(3)])
{
make1(n-3);
print();
}
else
{
if(!(n%2))
{
make1(n-2);
for(int i=1;i<n/2;i++)
{
make2();
make2();
make1(n-2);
}
make1(n-2);
print();
}
else
{
printf("NIE DA SIE\n");
}
}
}

BZOJ2214[Poi2011]Shift——模拟的更多相关文章

  1. Luogu3516 POI2011 Shift 构造

    传送门 题意:给出一个长为$N$的排列,有两种操作:$A$:将最后一个数字放到第一个:$B$:将第三个数字放到第一个.一次性使用某种操作$k$次写作$kA$或$kB$,其中在$kA$中$k < ...

  2. CF708A Letters Cyclic Shift 模拟

    You are given a non-empty string s consisting of lowercase English letters. You have to pick exactly ...

  3. Codeforces 960 二进制构造子序列 完全二叉树shift模拟 主席树/MAP DP

    A #include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #def ...

  4. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  5. POI做题笔记

    POI2011 Conspiracy (2-SAT) Description \(n\leq 5000\) Solution 发现可拆点然后使用2-SAT做,由于特殊的关系,可以证明每次只能交换两个集 ...

  6. Codeforces #259 Div.2

    A. Little Pony and Crystal Mine 模拟题. 用矩阵直接构造或者直接根据关系输出 B. Little Pony and Sort by Shift 模拟题. 通过提供的操作 ...

  7. [转] 有趣的JavaScript原生数组函数

    在JavaScript中,可以通过两种方式创建数组,Array构造函数和 [] 便捷方式, 其中后者为首选方法.数组对象继承自Object.prototype,对数组执行typeof操作符返回‘obj ...

  8. JavaScript原生数组函数

    有趣的JavaScript原生数组函数 在JavaScript中,可以通过两种方式创建数组,构造函数和数组直接量, 其中后者为首选方法.数组对象继承自Object.prototype,对数组执行typ ...

  9. 有趣的JavaScript原生数组函数

    本文由 伯乐在线 - yanhaijing 翻译.未经许可,禁止转载!英文出处:flippinawesome.欢迎加入翻译小组. 在JavaScript中,可以通过两种方式创建数组,Array构造函数 ...

随机推荐

  1. Linux命令——head/tail

    一.head head主要是用来显示档案的开头至标准输出中,默认打印相应文件的开头10 行. 1)命令格式 head [参数] [文件] 2)常用参数 -q     隐藏文件名-v     显示文件名 ...

  2. springMVC中上传图片

    上传图片,很常见的问题,基本每个人都会遇到,但是个人认为在springMVC中上传图片相对来说是比较简单的,因为框架已经帮我们做好了许多事情. 这篇文章所用的环境:spring4.3.3 .jdk1. ...

  3. async源码学习 - 全部源码

    因为工作需要,可能我离前端走远了,偏node方向了.所以异步编程的需求很多,于是乎,不得不带着学习async了. 我有个习惯,用别人的东西之前,喜欢稍微搞明白点,so就带着看看其源码. github: ...

  4. 解决Skyline6.5多球对比时,自动运行TerraExplorer软件的问题

    如果你的操作系统是Win7 64位,在运行Skyline6.5提供的ITE3DWindowEx控件实现多球对比时,启动程序调试运行时,却自动运行了TerraExplorer软件, 这时候你会发现for ...

  5. PHP_EOL换行 与 base64编码

    base64编码包括64个字符:10个数字(0-9),26*2个字母(a-zA-Z),+,/ 其中还有一个第65个字符=作为后缀,没有实际作用. 来一段代码说明个问题: <?php $str = ...

  6. webstorm破解汉化

    一.下载webstorm软件和汉化包 webstorm安装包下载链接 : 链接: https://pan.baidu.com/s/1VmOPNVL2GRgAb_0tAJhy8A 密码: am7e 汉化 ...

  7. Lean Data Innovation Sharing Salon(2018.09.15)

    时间:2018.09.15地点:北京国华投资大厦

  8. 使用TensorFlow的递归神经网络(LSTM)进行序列预测

    本篇文章介绍使用TensorFlow的递归神经网络(LSTM)进行序列预测.作者在网上找到的使用LSTM模型的案例都是解决自然语言处理的问题,而没有一个是来预测连续值的. 所以呢,这里是基于历史观察数 ...

  9. 案例学Python--案例四:Django实现一个网站的雏形(2)

    续上篇,用Django创建了一个Web,我们肯定想展示自己的页面,简单点,我们想看到自己的HelloWorld.此处要从项目的配置说起,方法和路径配对了,展现页面分分钟的事情. 先上效果图吧:     ...

  10. 因写太多 BUG!程序员遭公司颁奖羞辱,做的一个比一个绝​

    刚入职的程序员新人,办公桌上,基本上也就一电脑.一键盘.一鼠标,再配个被杯子.然而混迹职场多年的猿老们,办公桌上都有一些彰显身份地位的“好东西”. 这张图两点颇多,最显眼的,是办公桌上那个黄黄的东西, ...