hihocoder 1233 Boxes

题意:类汉诺塔的一个东西……移动规则与汉诺塔一样,但初始状态为题目中给出的每根棍上一个盘子,目标状态为盘子在棍上按大小顺序排列,盘子只能在相邻的棍儿上移动。

解法:广搜并打表记录从目标状态到所有可能的初始状态的答案。我记录每个盘子的位置为状态,vis用七位数组(被队友吐槽还真敢写啊=3=),然后每次转移状态的时候转化为每个棍儿上最小的盘子是啥(反正很抽象又不好解释……我懂就好啦哈哈哈哈哈哈哈哈哈哈(被队友嘲笑自暴自弃中))。答案的记录用转化为排列序数的方式。

代码:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<math.h>
#include<limits.h>
#include<time.h>
#include<stdlib.h>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define LL long long
using namespace std;
int ans[8][6000];
int fac[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};
int order(int v[], int len)//将排列转化为排列序数
{
    int i, j, temp, num;
    num = 0;
    for(i = 0; i < len - 1; i++)
    {
        temp = 0;
        for(j = i + 1; j < len; j++)
        {
            if(v[j] < v[i])
                temp++;
        }
        num += fac[v[i] - 1] * temp;
    }
    return num;
}
struct node
{
    int a[10], step;//a数组表示每个盘子放的棍儿的序号
    node(int tmp[], int tstep)
    {
        step = tstep;
        memcpy(a, tmp, sizeof a);
    }
    node() {}
};
bool vis[8][8][8][8][8][8][8];//记录状态
queue <node> q;
bool isanswer(int a[], int n)
{
    int stick[8] = {0, 100, 100, 100, 100, 100, 100, 100};
    for(int i = 0; i < n; i++)
        stick[a[i]] = min(stick[a[i]], i + 1);
    for(int i = 1; i <= n; i++)
        if(stick[i] == 100) return false;
    return true;
}
void bfs(int a[], int n)
{
    while(!q.empty()) q.pop();
    memset(vis, 0, sizeof vis);
    q.push(node(a, 0));
    vis[a[0]][a[1]][a[2]][a[3]][a[4]][a[5]][a[6]] = 1;
    while(!q.empty())
    {
        node tmp = q.front();
        q.pop();
        if(isanswer(tmp.a, n))
        {
            ans[n][order(tmp.a, n)] = tmp.step;
        }
        int stick[8] = {0, 100, 100, 100, 100, 100, 100, 100};
        for(int i = 0; i < n; i++)
            stick[tmp.a[i]] = min(stick[tmp.a[i]], i + 1);//算一下每根棍儿上最小的盘子是啥
        for(int i = 1; i <= n; i++)
        {
            if(stick[i] == 100) continue;
            if(i > 1 && (stick[i] < stick[i - 1] || (stick[i] != 100 && stick[i - 1] == 100)))//如果左面有棍儿且棍儿上最小的盘子比当前盘子大或者左面棍儿上没有盘子就转移状态
            {
                tmp.a[stick[i] - 1] = i - 1;
                if(!vis[tmp.a[0]][tmp.a[1]][tmp.a[2]][tmp.a[3]][tmp.a[4]][tmp.a[5]][tmp.a[6]])
                {
                    vis[tmp.a[0]][tmp.a[1]][tmp.a[2]][tmp.a[3]][tmp.a[4]][tmp.a[5]][tmp.a[6]] = 1;
                    q.push(node(tmp.a, tmp.step + 1));
                }
                tmp.a[stick[i] - 1] = i;
            }
            if(i < n && (stick[i] < stick[i + 1] || (stick[i] != 100 && stick[i + 1] == 100)))//同上
            {
                tmp.a[stick[i] - 1] = i + 1;
                if(!vis[tmp.a[0]][tmp.a[1]][tmp.a[2]][tmp.a[3]][tmp.a[4]][tmp.a[5]][tmp.a[6]])
                {
                    vis[tmp.a[0]][tmp.a[1]][tmp.a[2]][tmp.a[3]][tmp.a[4]][tmp.a[5]][tmp.a[6]] = 1;
                    q.push(node(tmp.a, tmp.step + 1));
                }
                tmp.a[stick[i] - 1] = i;
            }
        }
    }
}
void init()
{
    memset(ans, -1, sizeof ans);
    int a[] = {1, 2, 3, 4, 5, 6, 7};
    for(int i = 1; i < 8; i++)
        bfs(a, i);
}
int main()
{
    init();
    int T;
    scanf("%d", &T);
    while(T--)
    {
        int n, a[10], input[10];
        scanf("%d", &n);
        for(int i = 0; i < n; i++)
            scanf("%d", &input[i]);
        map <int, int> m;
        for(int i = 0; i < n; i++)
            m[input[i]] = i + 1;
        map <int, int> :: iterator ite = m.begin();
        for(int i = 0; ite != m.end(); ite++, i++) a[i] = ite -> second;
        int tmp = order(a, n);
        if(~ans[n][tmp])
            printf("%d\n", ans[n][tmp]);
        else
            printf("-1\n");
    }
    return 0;
}

  

时间: 2024-10-01 04:58:40

hihocoder 1233 Boxes的相关文章

hihoCoder 1233 : Boxes(盒子)

hihoCoder #1233 : Boxes(盒子) 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 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 i

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

第十四周 5.30 --- 6.5

新的一周 / w \ 大家都在图书馆看书..我在图书馆睡觉... 5.31 做cf 碰到一道 bfs 的题,想起这题还没有补 hiho 1233 Boxes 去年一神就教过我...可是又不会了.. 还是状态的表示没有想清楚,是每一个块的权值 乘以 位置的编号 表示一个状态 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include&l

2015年北京网赛 boxes(bfs)

题目链接: http://hihocoder.com/problemset/problem/1233 题目描述: 给定最多七个箱子,每个箱子的重量都不相同,每次都可以将一个箱子放在相邻的位置上,如果相邻位置上的箱子的重量比它大,那么可以放在相邻位置上的箱子, 小就不可以,问通过这样的操作最少需要多少步可以将这些箱子排好序? 由于最多是7个箱子,而且每个箱子的重量都不相同,那么最多有7!个状态,通过bfs每次需要更新的状态最多有12个状态,可以承受. 接下来就是怎样表示状态了,由于某一个位置可能会

[hihoCoder#1381]Little Y&#39;s Tree

[hihoCoder#1381]Little Y's Tree 试题描述 小Y有一棵n个节点的树,每条边都有正的边权. 小J有q个询问,每次小J会删掉这个树中的k条边,这棵树被分成k+1个连通块.小J想知道每个连通块中最远点对距离的和. 这里的询问是互相独立的,即每次都是在小Y的原树上进行操作. 输入 第一行一个整数n,接下来n-1行每行三个整数u,v,w,其中第i行表示第i条边边权为wi,连接了ui,vi两点. 接下来一行一个整数q,表示有q组询问. 对于每组询问,第一行一个正整数k,接下来一

hihoCoder 1175:拓扑排序二

题目链接: http://hihocoder.com/problemset/problem/1175 题目难度:一星级(简单题) 今天闲来无事,决定刷一道水题.结果发现这道水题居然把我卡了将近一个钟头. 最后终于调通了.总结起来,原因只有一个:不够仔细. 思路不用细说了,就是拓扑排序的简单应用.然而,一些不起眼的细节才是让你掉坑里的真正原因. 猜猜哪儿可能出bug? // A simple problem, but you can't be too careful with it. #inclu

uva 12657 - Boxes in a Line(AC和TLE的区别,为什么说STL慢..)

用STL中的list写的,TLE #include<cstdio> #include<iostream> #include<cstring> #include<list> #include<algorithm> using namespace std; list<int> l; list<int>::iterator it1,it2,it3,it4,it5,it; void work(int a,int a1=1,int

hihocoder [Offer收割]编程练习赛18 C 最美和弦(dp)

题目链接:http://hihocoder.com/problemset/problem/1532 题解:一道基础的dp,设dp[i][j][k][l]表示处理到第几个数,当前是哪个和弦错了几次初始x值是多少.这里还要再辅助一个val[k]表示处理到当前情况只错了k次的最小值是多少因为改变的不止是和弦还有初始值,可以看一下代码理解一下. #include <iostream> #include <cstring> #include <cstdio> #include &

[LeetCode] Remove Boxes 移除盒子

Given several boxes with different colors represented by different positive numbers. You may experience several rounds to remove boxes until there is no box left. Each time you can choose some continuous boxes with the same color (composed of k boxes