SDUT 3571 Password 暴力搜索

这个题如果裸搜肯定超时了

但是我们可以枚举,用初始串的哪一位数字去填目标串的那一位数字

这样就是暴力6!,复杂度很低,然后需要解决过程中经过的点的问题,

因为是从左向右走,所以记录当前光标,

和当前达到的最右端

所以复杂度是O(T*36*(6!)),2000w的复杂度

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <vector>
#include <cmath>
#include <queue>
#include <map>
#include <string>
using namespace std;
typedef long long LL;
const int N=1e6+5;
const int INF=0x3f3f3f3f;
int vis[N][7][7];
int f[]= {100000,10000,1000,100,10,1};
int left(int x,int p)
{
    int k1=x/f[p]%10;
    int k2=x/f[p-1]%10;
    return x+(k2-k1)*f[p]+(k1-k2)*f[p-1];
}
int right(int x,int p)
{
    return left(x,p+1);
}
int judge(int x,int y,int l,int r)
{
    int ret=0;
    for(int i=l; i<=r; ++i)
        ret+=abs((x/f[i]%10)-(y/f[i]%10));
    return ret;
}
struct Node
{
    int x,p,mx,step;
    Node() {}
    Node(int a,int b,int c,int d)
    {
        x=a;
        p=b;
        mx=c;
        step=d;
    }
};
queue<Node>q;
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int s,t;
        scanf("%d%d",&s,&t);
        q.push(Node(s,0,0,0));
        vis[s][0][0]=++T;
        int ans=INF;
        while(!q.empty())
        {
            Node u=q.front();
            q.pop();
            if(u.step>=ans)continue;
            if(u.p>0)
            {
                Node v=u;++v.step;
                --v.p;
                if(vis[v.x][v.p][v.mx]!=T)
                {
                    vis[v.x][v.p][v.mx]=T;
                    q.push(v);
                }
            }
            if(u.p<5)
            {
                Node v=u;
                ++v.p;++v.step;
                v.mx=max(v.mx,v.p);
                if(vis[v.x][v.p][v.mx]!=T)
                {
                    vis[v.x][v.p][v.mx]=T;
                    if(judge(v.x,t,v.mx+1,5)==0)
                        ans=min(ans,judge(v.x,t,0,v.mx)+v.step);
                    q.push(v);
                }
            }
            if(u.p>0)
            {
                Node v=u;++v.step;
                v.x=left(v.x,v.p);
                if(vis[v.x][v.p][v.mx]!=T)
                {
                    vis[v.x][v.p][v.mx]=T;
                    if(judge(v.x,t,v.mx+1,5)==0)
                        ans=min(ans,judge(v.x,t,0,v.mx)+v.step);
                    q.push(v);
                }
            }
            if(u.p<5)
            {
                Node v=u;++v.step;
                v.x=right(v.x,v.p);
                v.mx=max(v.mx,v.p+1);
                if(vis[v.x][v.p][v.mx]!=T)
                {
                    vis[v.x][v.p][v.mx]=T;
                    if(judge(v.x,t,v.mx+1,5)==0)
                        ans=min(ans,judge(v.x,t,0,v.mx)+v.step);
                    q.push(v);
                }
            }
        }
        --T;
        printf("%d\n",ans);
    }

    return 0;
}

时间: 2024-08-23 00:30:48

SDUT 3571 Password 暴力搜索的相关文章

[暴力搜索] POJ 3087 Shuffle&#39;m Up

Shuffle'm Up Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10003   Accepted: 4631 Description A common pastime for poker players at a poker table is to shuffle stacks of chips. Shuffling chips is performed by starting with two stacks o

HDU 3699 A hard Aoshu Problem (暴力搜索)

题意:题意:给你3个字符串s1,s2,s3;要求对三个字符串中的字符赋值(相同的字符串进行相同的数字替换), 替换后的三个数进行四则运算要满足左边等于右边,求有几种解法. Sample Input 2 A A A BCD BCD B Sample Output 5 72 eg:ABBDE   ABCCC   BDBDE :令 A = 1, B = 2, C = 0, D = 4, E = 5 12245 + 12000 = 24245: 注意没有前导零!! #include<stdio.h>

HDU 4499 Cannon (暴力搜索)

题意:在n*m的方格里有t个棋子,问最多能放多少个炮且每个炮不能互相攻击(炮吃炮) 炮吃炮:在同一行或同一列且中间有一颗棋子. #include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> #include <queue> #include <math.h> #define M 50 #define LL long long using

poj 1054 The Troublesome Frog (暴力搜索 + 剪枝优化)

题目链接 看到分类里是dp,结果想了半天,也没想出来,搜了一下题解,全是暴力! 不过剪枝很重要,下面我的代码 266ms. 题意: 在一个矩阵方格里面,青蛙在里面跳,但是青蛙每一步都是等长的跳, 从一个边界外,跳到了另一边的边界外,每跳一次对那个点进行标记. 现在给你很多青蛙跳过后的所标记的所有点,那请你从这些点里面找出 一条可能的路径里面出现过的标记点最多. 分析:先排序(目的是方便剪枝,break),然后枚举两个点,这两个 点代表这条路径的起始的两个点.然后是三个剪枝,下面有. 开始遍历时,

hdu 1399 Starship Hakodate-maru (暴力搜索)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1399 题目大意:找到满足i*i*i+j*(j+1)*(j+2)/6形式且小于等于n的最大值. 1 #include<iostream> 2 #include<cstdio> 3 4 using namespace std; 5 6 int main() 7 { 8 int n; 9 while(scanf("%d",&n),n) 10 { 11 int j,

ACM 暴力搜索题 题目整理

UVa 129 Krypton Factor 注意输出格式,比较坑爹. 每次要进行处理去掉容易的串,统计困难串的个数. #include<iostream> #include<vector> #include<cmath> #include<map> #include<algorithm> #include<cstring> #include<cstdio> #include<cstdlib> #include

Codeforces Round #224 (Div. 2) D 暴力搜索加记忆化

题意读了半年,英语太渣,题意是摆两个棋子在棋盘上作为起点,但是起点不能在#上,然后按照图的指示开始走, < 左 > 右 ^上 v下,走的时候只能按照图的指示走,如果前方是 #的话,可以走进去,但是 走进去之后便不能再走了,走的途中两个棋子不能相碰,但是最终都走到同一个#里是没事的,并且若是能走 无限步的话 输出 -1, 例如  > < 这样左右左右的走就能无限走,然后问你 两个棋子走的最大步数的和 一开始被输出-1给困住了,因为除了 .> <这样以外  还可以刚好形成一

POJ 2329 (暴力+搜索bfs)

Nearest number - 2 Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 3943 Accepted: 1210 Description Input is the matrix A of N by N non-negative integers. A distance between two elements Aij and Apq is defined as |i ? p| + |j ? q|. Your pro

POJ 2110 Mountain Walking 暴力搜索+二分

题意:n*n的矩阵 每次能走四个方向,定义路径的花费为:路径中方格的max-min,问从左上到右下的最小花费,n<=100 4个方向不是DAG,不能DP,暴力搜索 每个点最坏情况下走n*n 共n*n个点 O(n^4)TLE二分ans后 枚举下界,则此时知道路径的最小值和最大值从 起点出发把mn<=c<=mx的点都遍历,此时dfs 相当于遍历图,不用回溯,复杂度为O(n^3*logn) #include <iostream> #include <cstring> #