2015年北京网赛 boxes(bfs)

题目链接:

http://hihocoder.com/problemset/problem/1233

题目描述:

给定最多七个箱子,每个箱子的重量都不相同,每次都可以将一个箱子放在相邻的位置上,如果相邻位置上的箱子的重量比它大,那么可以放在相邻位置上的箱子,

小就不可以,问通过这样的操作最少需要多少步可以将这些箱子排好序?

由于最多是7个箱子,而且每个箱子的重量都不相同,那么最多有7!个状态,通过bfs每次需要更新的状态最多有12个状态,可以承受。

接下来就是怎样表示状态了,由于某一个位置可能会有很多个数,所以不能直接记录,可以记录每个数所在的位置来表示状态。

还有一点就是需要将大数化小数,同样是记录位置,然后排个序,找出它们之间的大小关系,就可以大数化小数了。

#include <stdio.h>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
int vis2[8][8];
int vis3[8][8][8];
int vis4[8][8][8][8];
int vis5[8][8][8][8][8];
int vis6[8][8][8][8][8][8];
int vis7[8][8][8][8][8][8][8];
bool check(int a[],int n,int step){
    if(n==2){
        if(vis2[a[1]][a[2]]!=-1) return 0;
        else {
            vis2[a[1]][a[2]]=step;return 1;
        }
    }
    else if(n==3){
        if(vis3[a[1]][a[2]][a[3]]!=-1) return 0;
        else {
            vis3[a[1]][a[2]][a[3]]=step;return 1;
        }
    }
    else if(n==4){
        if(vis4[a[1]][a[2]][a[3]][a[4]]!=-1) return 0;
        else {
            vis4[a[1]][a[2]][a[3]][a[4]]=step;return 1;
        }
    }
    else if(n==5){
        if(vis5[a[1]][a[2]][a[3]][a[4]][a[5]]!=-1) return 0;
        else {
            vis5[a[1]][a[2]][a[3]][a[4]][a[5]]=step;return 1;
        }
    }
    else if(n==6){
        if(vis6[a[1]][a[2]][a[3]][a[4]][a[5]][a[6]]!=-1) return 0;
        else {
            vis6[a[1]][a[2]][a[3]][a[4]][a[5]][a[6]]=step;return 1;
        }
    }
    else if(n==7){
        if(vis7[a[1]][a[2]][a[3]][a[4]][a[5]][a[6]][a[7]]!=-1) return 0;
        else {
            vis7[a[1]][a[2]][a[3]][a[4]][a[5]][a[6]][a[7]]=step;return 1;
        }
    }
}
struct node
{
    int pos[10];
    int step;
};
void bfs(int n)
{
     int a[10];
     node start;
     for(int i=1;i<=n;i++)
          a[i]=i;
     check(a,n,0); //首先初始化,起始状态step等于0
     for(int i=1;i<=n;i++)
        start.pos[i]=i;
     start.step=0;
     queue < node >  que;
     que.push(start);
     while(!que.empty())
     {
         node cur=que.front();
         que.pop();
         for(int i=1;i<=n;i++)
         {
             int l=0,r=0;
             for(int j=1;j<i;j++)
             {
                 if(cur.pos[j]==cur.pos[i]-1)  l=1; //l==1,说明左边比它小,不能往左移
                 if(cur.pos[j]==cur.pos[i]+1)  r=1;
                 if(cur.pos[j]==cur.pos[i])    l=r=1;//不能左移或者右移
             }
             if(cur.pos[i]-1<1)     l=1;
             if(cur.pos[i]+1>n)     r=1;
             if(l==0)
             {
                 cur.pos[i]--;  cur.step++;
                 if(check(cur.pos,n,cur.step))   que.push(cur);
                 cur.pos[i]++;  cur.step--;
             }
             if(r==0)
             {
                 cur.pos[i]++;  cur.step++;
                 if(check(cur.pos,n,cur.step))   que.push(cur);
                 cur.pos[i]--;  cur.step--;
             }
         }
     }
}
void init()
{
    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));
    for(int i=2;i<=7;i++)
        bfs(i);
}
struct num
{
       int data,id;
}input[10];
bool cmp(num a,num b)
{
   if(a.data<b.data)
    return 1;
   else
     return 0;
}
int main()
{
    int b[10];
   // freopen("test.txt","r",stdin);
    int t;
    scanf("%d",&t);
    init();
    while(t--)
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&input[i].data);
            input[i].id=i;
        }
        sort(input+1,input+n+1,cmp);
        for(int i=1;i<=n;i++)
        {
            b[i]=input[i].id;
        }
        if(n==1)
            printf("0\n");
        if(n==2)
        printf("%d\n",vis2[b[1]][b[2]]);
        if(n==3)
        printf("%d\n",vis3[b[1]][b[2]][b[3]]);
        if(n==4)
        printf("%d\n",vis4[b[1]][b[2]][b[3]][b[4]]);
        if(n==5)
        printf("%d\n",vis5[b[1]][b[2]][b[3]][b[4]][b[5]]);
        if(n==6)
        printf("%d\n",vis6[b[1]][b[2]][b[3]][b[4]][b[5]][b[6]]);
        if(n==7)
        printf("%d\n",vis7[b[1]][b[2]][b[3]][b[4]][b[5]][b[6]][b[7]]);
    }
    return 0;
}
时间: 2024-11-08 23:19:52

2015年北京网赛 boxes(bfs)的相关文章

ACM学习历程—Hihocoder 1233 Boxes(bfs)(2015北京网赛)

hihoCoder挑战赛12 时间限制:1000ms 单点时限:1000ms 内存限制:256MB   描述 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

hihocoder-1389&amp;&amp;2016北京网赛07 Sewage Treatment(二分+网络流)

题目链接: Sewage Treatment 时间限制:2000ms 单点时限:2000ms 内存限制:256MB 描述 After years of suffering, people could not tolerate the pollution in the city any more, and started a long-lasting protest. Eventually, the municipal government made up its mind to deal wit

2015年沈阳网赛 Jesus Is Here(DP中的计数问题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5459 题目描述:给定一个递推得来的字符串,问字符串中不同cff之间的距离之和, 递推规则: s1=c; s2=ff sn=s[n-2]s[n-1]; 可以观察到任意一个c都被两个ff包含,所以相当于求任意两个c之间的距离之和. 设s[n-2]为p1,p2,p3,,,,p[x],s[n-1]为q1,q2,q3,,,,q[y]; X和y分别为字符串中c的个数:设cnt_c[i]为第i个字符串中c的个数,

hihoCoder1388 Periodic Signal(2016北京网赛F:NTT)

题目 Source http://hihocoder.com/problemset/problem/1388 Description Profess X is an expert in signal processing. He has a device which can send a particular 1 second signal repeatedly. The signal is A0 ... An-1 under n Hz sampling. One day, the device

2015北京网络赛A题The Cats&#39; Feeding Spots

题意:给你一百个点,找个以这些点为中心的最小的圆,使得这个圆恰好包含了n个点,而且这个圆的边界上并没有点 解题思路:暴力枚举每个点,求出每个点到其他点的距离,取第n大的点,判断一下. 1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 #include<iostream> 5 #include<memory.h> 6 using namespace std; 7 const i

2015北京网络赛 Couple Trees 倍增算法

2015北京网络赛 Couple Trees 题意:两棵树,求不同树上两个节点的最近公共祖先 思路:比赛时看过的队伍不是很多,没有仔细想.今天补题才发现有个 倍增算法,自己竟然不知道.  解法来自 qscqesze ,这个其实之前如果了解过倍增的话还是不是很难,不过这题的数据也不是很给力,极限数据理论上是过不了的.  其他解法有树链剖分?并不是很清楚.就这样水过了吧... 1 #include <iostream> 2 #include <cstdio> 3 #include &l

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)为满足x≤ai≤m+x且ai的异或和为0 的序列a的个数. 求 ∑Rx=Lf(x)mod1000000007 思路:因为对于每一个第一次分配后的a序列对应唯一的x,所以我们就枚举x然后在求序列的个数.

2015北京区域赛 Xiongnu&#39;s Land

Wei Qing (died 106 BC) was a military general of the Western Han dynasty whose campaigns against the Xiongnu earned him great acclaim. He was a relative of Emperor Wu because he was the younger half-brother of Empress Wei Zifu (Emperor Wu's wife) and

15北京区域赛——A 二分——hihoCoder 1249 Xiongnu&#39;s Land

两次二分,第一次取得最小值,第二次往右二分看是否能到更右边 注意超出部分land部分要去掉 #include <cstdio> #include <algorithm> using namespace std; typedef long long ll; struct edge{ int x, y, w, h; }a[10010]; bool cmp(edge A, edge B) { return A.x < B.x; } int n; ll cal(int x) { ll