zoukankan      html  css  js  c++  java
  • noip模拟赛 PA

    分析:很显然这是一道搜索题,可能是由于我的搜索打的太不美观了,这道题又WA又T......如果对每一个询问都做一次bfs是肯定会T的,注意到前70%的数据范围,N的值都相等,我们可以把给定N的所有情况给算出来,然后O(1)查询.从终点状态往起点状态BFS就可以了.

    当最终状态很少,起始状态很多的时候,可以考虑倒着做.

    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    int T, jian[10], stu, shu[10], cnt, top[10], d[10000000], cur[10], vis[10000000];
    int n, a[10], b[10];
    queue <int> q;
    
    bool cmp(int x, int y)
    {
        return a[x] < a[y];
    }
    
    void bfs()
    {
        while (!q.empty())
        {
            int zhuangtai = q.front();
            q.pop();
            memset(top, 0, sizeof(top));
            memset(shu, 0, sizeof(shu));
            cnt = 0;
            int tt = zhuangtai;
            while (tt)
            {
                shu[++cnt] = tt % 10;
                tt /= 10;
            }
            reverse(shu + 1, shu + 1 + cnt);
            for (int i = cnt; i >= 1; i--)
                top[shu[i]] = i;
            for (int i = 1; i <= cnt; i++)
                if (i == top[shu[i]])
                {
                int temp = shu[i];
                if (temp != 1 && (i < top[temp - 1] || !top[temp - 1]))
                {
                    int newstu = zhuangtai - jian[cnt - i];
                    if (!vis[newstu])
                    {
                        q.push(newstu);
                        vis[newstu] = 1;
                        d[newstu] = d[zhuangtai] + 1;
                    }
                }
    
                if (temp != cnt && (i < top[temp + 1] || !top[temp + 1]))
                {
                    int newstu = zhuangtai + jian[cnt - i];
                    if (!vis[newstu])
                    {
                        q.push(newstu);
                        vis[newstu] = 1;
                        d[newstu] = d[zhuangtai] + 1;
                    }
                }
                }
        }
    }
    
    int main()
    {
        scanf("%d", &T);
        jian[0] = 1;
        stu = 0;
        for (int i = 1; i <= 7; i++)
        {
            jian[i] = jian[i - 1] * 10;
            stu = stu * 10 + i;
            q.push(stu);
            vis[stu] = 1;
        }
        bfs();
        //printf("flag
    ");
        while (T--)
        {
            scanf("%d", &n);
            for (int i = 1; i <= n; i++)
            {
                scanf("%d", &a[i]);
                b[i] = i;
            }
            sort(b + 1, b + 1 + n, cmp); 
            int stu = 0;
            for (int i = 1; i <= n; i++)
                stu = stu * 10 + b[i];
            if (!vis[stu])
                printf("-1
    ");
            else
                printf("%d
    ", d[stu]);
        }
    
        return 0;
    }
  • 相关阅读:
    常用模块Part(1)
    递归函数
    python 生成器函数
    python 迭代器与生成器
    python 函数进阶
    python 装饰器进阶
    python time模块
    python 初始函数
    python 文件操作
    python 一些小知识
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7716385.html
Copyright © 2011-2022 走看看