北京网络赛G BOXES 大模拟+BFS
题目描述
Description
There is a strange storehouse in PKU. In this storehouse there are n slots for boxes, forming a line. In each slot you can pile up any amount of boxes. The limitation is that you can only pile a smaller one above a bigger one, in order to keep balance. The slots are numbered from 1 to n. The leftmost one is slot 1.
At first there is exactly one box in each slot. The volume of the box in slot i is vi. As a virgo, you decide to sort these boxes by moving some of them. In each move you can choose a slot and move the top box in this slot to an adjacent slot (of course you can only put it on the top). You should ensure that the limitation mentioned above is still satisfied after this move. After the sort operation, there should be exactly one box in each slot, and for each pair of adjacent slots, the box in the left one should be smaller than the box in the right one.
Your task is to calculate the minimum number of moves you need to sort the boxes.
Input
In the first line there’s an integer T(T≤6000), indicating the number of test cases. The following 2T lines describe the test cases.
In each test case, the first line contains an integer n, indicating the number of slots. The second line contains n integers v1,v2…vn, indicating the volume of the boxes. It is guaranteed that all vi in a test case are different.
Please note that n<8,0≤vi≤104
Output
For each test case, print a line containing one integer indicating the answer. If it’s impossible to sort the boxes, print -1.
- Sample Input
-
4
3
2 1 3
2
7 8
2
10000 1000
3
97 96 95 - Sample Output
-
4
0
-1
20#include <bits/stdc++.h>
using namespace std;
int vis1[7];
int vis2[7][7];
int vis3[7][7][7];
int vis4[7][7][7][7];
int vis5[7][7][7][7][7];
int vis6[7][7][7][7][7][7];
int vis7[7][7][7][7][7][7][7];
struct node{
int a[7];
int step;
};
map<int,int> Hash;
int a[10],b[10],c[10];
bool check(int a[],int num,int step){
if(num==1){
if(vis1[a[0]]>=0) return true;
else{vis1[a[0]]=step;return false;}
}
if(num==2){
if(vis2[a[0]][a[1]]>=0) return true;
else {vis2[a[0]][a[1]]=step;return false;}
}
if(num==3){
if(vis3[a[0]][a[1]][a[2]]>=0) return true;
else {vis3[a[0]][a[1]][a[2]]=step;return false;}
}
if(num==4){
if(vis4[a[0]][a[1]][a[2]][a[3]]>=0) return true;
else {vis4[a[0]][a[1]][a[2]][a[3]]=step;return false;}
}
if(num==5){
if(vis5[a[0]][a[1]][a[2]][a[3]][a[4]]>=0) return true;
else {vis5[a[0]][a[1]][a[2]][a[3]][a[4]]=step;return false;}
}
if(num==6){
if(vis6[a[0]][a[1]][a[2]][a[3]][a[4]][a[5]]>=0) return true;
else {vis6[a[0]][a[1]][a[2]][a[3]][a[4]][a[5]]=step;return false;}
}
if(num==7){
if(vis7[a[0]][a[1]][a[2]][a[3]][a[4]][a[5]][a[6]]>=0) return true;
else {vis7[a[0]][a[1]][a[2]][a[3]][a[4]][a[5]][a[6]]=step;return false;}
}
return false;
}
void init(){
memset(vis1,-1,sizeof(vis1));
memset(vis2,-1,sizeof(vis2));
memset(vis3,-1,sizeof(vis3));
memset(vis4,-1,sizeof(vis4));
memset(vis5,-1,sizeof(vis5));
memset(vis6,-1,sizeof(vis6));
memset(vis7,-1,sizeof(vis7));
}
void bfs(int a[],int num){
node k;k.step=0;
for(int i=0;i<num;i++){k.a[i]=i;}
check(a,num,0);
queue<node> que;que.push(k);
int b[7];
while(!que.empty()){
node top=que.front();que.pop();
for(int i=0;i<num;++i)
b[i]=top.a[i];
for(int i=0;i<num;++i){
int l=b[i]-1;
int r=b[i]+1;
if(l<0) l=-1;
if(r>=num) r=-1;
for(int j=0;j<i;++j) if(b[j]==b[i]){l=r=-1;}
for(int j=0;j<i;++j) if(b[j]==b[i]-1) {l=-1;}
for(int j=0;j<i;++j) if(b[j]==b[i]+1) {r=-1;}
if(l!=-1){
int temp=b[i];
b[i]=l;
node s;
for(int j=0;j<num;++j) {s.a[j]=b[j];}
s.step=top.step+1;
if(!check(b,num,s.step)){
que.push(s);
}
b[i]=temp;
}
if(r!=-1){
int temp=b[i];
b[i]=r;
node s;
for(int j=0;j<num;++j) {s.a[j]=b[j];}
s.step=top.step+1;
if(!check(b,num,s.step)){
que.push(s);
}
b[i]=temp;
}
}
}
} int main(){
int T,n;
for(int i=0;i<7;i++){
a[i]=i;
}
init();
for(int i=1;i<=7;i++){
bfs(a,i);
}
for(scanf("%d",&T);T;--T){
scanf("%d",&n);Hash.clear();
vector<int> Q;
for(int i=0;i<n;i++){
scanf("%d",b+i);
Q.push_back(b[i]);
}
sort(Q.begin(),Q.end());
for(int i=0;i<(int)Q.size();i++){
Hash[Q[i]]=i;
}
for(int i=0;i<n;i++){
c[Hash[b[i]]]=i;
}
if(n==1){
if(c[0]==0){
printf("0\n");
}
else printf("%d\n",vis1[c[0]]);
}
if(n==2){
if(c[0]==0&&c[1]==1){
printf("0\n");
}
else printf("%d\n",vis2[c[0]][c[1]]);
}
if(n==3){
if(c[0]==0&&c[1]==1&&c[2]==2){
printf("0\n");
}
else printf("%d\n",vis3[c[0]][c[1]][c[2]]);
}
if(n==4){
if(c[0]==0&&c[1]==1&&c[2]==2&&c[3]==3){
printf("0\n");
}
else printf("%d\n",vis4[c[0]][c[1]][c[2]][c[3]]);
}
if(n==5){
if(c[0]==0&&c[1]==1&&c[2]==2&&c[3]==3&&c[4]==4){
printf("0\n");
}
else printf("%d\n",vis5[c[0]][c[1]][c[2]][c[3]][c[4]]);
}
if(n==6){
if(c[0]==0&&c[1]==1&&c[2]==2&&c[3]==3&&c[4]==4&&c[5]==5){
printf("0\n");
}
else printf("%d\n",vis6[c[0]][c[1]][c[2]][c[3]][c[4]][c[5]]);
}
if(n==7){
if(c[0]==0&&c[1]==1&&c[2]==2&&c[3]==3&&c[4]==4&&c[5]==5&&c[6]==6){
printf("0\n");
}
else printf("%d\n",vis7[c[0]][c[1]][c[2]][c[3]][c[4]][c[5]][c[6]]);
}
}
return 0;
}
首先对之前搜到这个题解的人说声对不起,因为之前写的有问题也没修补
好了我来解释一下代码的关键部分。。。
好的,这其实是个sb题,没睡醒的同学可以看一下下面的解释。。。
首先是状态定义
a[i]:第i大的元素在值为a[i]的位置上
然后,我们可以离线地做这道题
初始状态有序让a[i]=i
然后让他去搜索所有有效的状态,因为你正着搜结果和结果往乱了推其实值是一样的,这是一个可逆的过程
然后我们使用bfs爆搜所有从有序状态出发的状态并且记录答案
bfs中的关键判断是
1,这个第i大的元素,上面有没有东西
检查方法,遍历0~i-1大的元素,看一下这些元素里有没有和它在同一个位置
2,相邻的右边的柱子能不能放东西
检查方法,遍历0~i-1大的元素,看一下这些元素有没有放到a[i]+1这个槽里,只要有那么至少是不能放的,因为只可能更小
3,相邻的左边的柱子能不能放东西
检查方法,遍历0~i-1大的元素,看一下这些元素有没有放到a[i]-1这个槽里,只要有那么至少是不能放的,因为只可能更小
然后就是复制状态,检查访问过没有,判断一下加入队列
然后就是一些细节的东西
数组下标什么的千万别搞混。。。离散化之后记得维护c[i]的意义,千万别直接扔个rank数组进去...
北京网络赛G BOXES 大模拟+BFS的更多相关文章
- 2015北京网络赛 G Boxes BFS+打表
G Boxes 题意:n个位置摆有n个箱子,每次移动只能把相邻的垒起来,且上面的必须小于下面的.求摆成升序需要移动多少步. 思路:这里的n很小,只有7.但是bfs最快的情况需要2s左右,所以就打表了. ...
- 北京网络赛G BOXES 状态压缩+有序BFS+高维数组判重
#include <bits/stdc++.h> using namespace std; ]; ][]; ][][]; ][][][]; ][][][][]; ][][][][][]; ...
- 2015北京网络赛 G题 Boxes bfs
Boxes Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://hihocoder.com/contest/acmicpc2015beijingonl ...
- hihocode 1584 : Bounce (找规律)(2017 北京网络赛G)
题目链接 比赛时随便找了个规律,然后队友过了.不过那个规律具体细节还挺烦的.刚刚偶然看到Q巨在群里提到的他的一个思路,妙啊,很好理解,而且公式写起来也容易.OrzQ巨 #include<bits ...
- hdu 5038 (2014北京网络赛G 排序水题)
题意:有n个数字,带入10000 - (100 - ai) ^ 2公式得到n个数,输出n个数中频率最大的数,如果有并列就按值从小到大都输出输出,如果频率相同的数字是全部的n个数,就输出Bad....题 ...
- 2018北京网络赛 G The Mole /// 分块暴力 点线距离
题目大意: 给定n段线段 编号为1~n 接下来m个询问 给定一点 输出离该点最近的线段的最小编号(距离相等时取编号小的) 题解 大致就是 1.坐标范围为(0,2^16-1) 将坐标系划分为2^8*2^ ...
- hihocoder1236(北京网络赛J):scores 分块+bitset
北京网络赛的题- -.当时没思路,听大神们说是分块+bitset,想了一下发现确实可做,就试了一下,T了好多次终于过了 题意: 初始有n个人,每个人有五种能力值,现在有q个查询,每次查询给五个数代表查 ...
- 2015北京网络赛 D-The Celebration of Rabbits 动归+FWT
2015北京网络赛 D-The Celebration of Rabbits 题意: 给定四个正整数n, m, L, R (1≤n,m,L,R≤1000). 设a为一个长度为2n+1的序列. 设f(x ...
- 2015北京网络赛 J Scores bitset+分块
2015北京网络赛 J Scores 题意:50000组5维数据,50000个询问,问有多少组每一维都不大于询问的数据 思路:赛时没有思路,后来看解题报告也因为智商太低看了半天看不懂.bitset之前 ...
随机推荐
- Py迭代和迭代器,生成器,生产者和消费者模型
迭代器iter 1.迭代的含义: 每次生成的结果依赖于上一次.问路,先问第一个人,第一个人不知道他就说第二个人知道,然后去找第二个人.第二个人不知道就说第三个人知道,然后去找第三个人 2.递归的含义: ...
- IDEA SSM后端框架入门
SSM框架 如果对SSM一无所知,推荐先去看这本书,可以在微信读书上看. 知识点 控制器返回对象时,对象需要有getter,setter方法,才能自动转化为json数据类型. 一个服务管理者对应多个业 ...
- 服务之间的调用为啥不直接用 HTTP 而用 RPC?
什么是 RPC?RPC原理是什么? 什么是 RPC? RPC(Remote Procedure Call)-远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议.比 ...
- (八)整合 Dubbo框架 ,实现RPC服务远程调用
整合 Dubbo框架 ,实现RPC服务远程调用 1.Dubbo框架简介 1.1 框架依赖 1.2 核心角色说明 2.SpringBoot整合Dubbo 2.1 核心依赖 2.2 项目结构说明 2.3 ...
- CSS定位走一波(定位学习续)
又是新的一周过去了,时间到了,春天绿了,关于HTML5的学习进步了,今天博客更新一些CSS定位的内容,小的一些细节也要牢记,方便做一个更完美的项目. 如何让垂直方向居中,解决方式:在父元素添加over ...
- GeoJson的生成与解析,JSON解析,Java读写geojson,geotools读取shp文件,Geotools中Geometry对象与GeoJson的相互转换
GeoJson的生成与解析 一.wkt格式的geometry转成json格式 二.json格式转wkt格式 三.json格式的数据进行解析 四.Java读写geojson 五.geotools读取sh ...
- dedecms文章页的上下篇颠倒的问题
dedecms的文章页底下的上下篇,如果按照时间排序的话,最新的一篇应该是最上了,但是底下还是会显示上一篇文章还有,然后下一篇文章没有了,就是颠倒了.如何修改呢. 1.修改include目录下arc. ...
- 从零开始教你安装Oracle数据库
1.数据库安装 1.1下载 根据自己的操作系统位数,到oracle官网下载(以oracle 11g 为例) 之后把两个压缩包解压到同一个文件夹内(需要注意的是,这个文件夹路径名称中最好不要出现中文.空 ...
- F - F(最小生成树)
题意:连通各点最短距离,最小生成树. You are assigned to design network connections between certain points in a wide a ...
- 最短路径问题---Floyed(弗洛伊德算法),dijkstra算法,SPFA算法
在NOIP比赛中,如果出图论题最短路径应该是个常考点. 求解最短路径常用的算法有:Floyed算法(O(n^3)的暴力算法,在比赛中大概能过三十分) dijkstra算法 (堆优化之后是O(MlogE ...