首页 > 其他分享 >每天一道蓝桥杯 Day3 移动字母

每天一道蓝桥杯 Day3 移动字母

时间:2024-03-09 23:11:21浏览次数:17  
标签:状态 终点 ty int 字母 bfs Day3 dfs 蓝桥

 

题意:

 

思考过程:

首先观察这道题的数据范围不是很大,一共才6个位置,并且每个位置只出现一次。

那么不考虑合法,只算总状态的话就是7*6*5*4*3*2*1=720

状态数很少,启发我们可以用搜索!

那么搜索是用dfs还是bfs?

bfs有一个特性:从s出发,第一次搜索到状态t时所用的步数,肯定是所需的最小操作次数。

因为bfs每次扩展时只多走一步,假设第一次到某个点所用步数为c,最优解为c'

如果c'<=c,bfs每次会把能扩展的都扩展掉,则一定会更早扩展到c'而不是c。

这个性质有一个直观的呈现:图中蓝色的是起点,绿色的是终点,红色的是障碍物,粉色的是最优解。

而dfs则不一定,有可能存在更优的解法,要全部搜索完才能找到最优解。

再回头看这道题,由于只询问是否可达,不问最优解的话,那dfs或者bfs都可以。

用dfs实现:

实现上也有一些小技巧。

1.读入的是字符串,但是实际上移动时又是在一个2*3的字符数组上向上下左右移动。

直接分位置讨论的话由于数据小也是可行的,不过可以考虑引入方向数组

dx[4]={0,0,-1,1},dy[4]={1,-1,0,0}

//假设当前在的位置是(x,y),拓展时只需要

for(int i=0;i<4;i++){
     int tx=x+dx[i],ty=y+dy[i];  
}

就可以省去分类讨论的麻烦。

2.像这种终点明确,起点很多的询问,如果操作是可逆的,就可以考虑从终点出发,预处理出所有可达的状态。

具体地,我们可以从"ABCDE*"出发,dfs出所有能到的状态,把能到的状态打标记。

处理询问时,只需要查询这个状态有没有被搜索过。

代码:

#include<bits/stdc++.h>
using namespace std;
int dx[4]={0,0,-1,1};
int dy[4]={-1,1,0,0};
char a[3][7];
map<string,int>mp;
int cnt=0;
string check( ){
    string s="";//把数组再转回字符串,方便用map存储
    for(int i=1;i<=2;i++)
     for(int j=1;j<=3;j++){
        s=s+a[i][j];
     }
    return s;
}
void dfs(int x,int y){
    if(mp[check( )]) return;
    mp[check( )]=1;//对当前访问到的状态打标记,防止之后又被搜索,时间复杂度将会很大。
    for(int i=0;i<4;i++){
        int tx=x+dx[i],ty=y+dy[i];
        if(tx<=2&&tx>=1&&ty<=3&&ty>=1){//拓展的格子肯定不能越界
            swap(a[tx][ty],a[x][y]);
            dfs(tx,ty);
            swap(a[tx][ty],a[x][y]);//回溯
        } 
    } 
}
void solve(){
    a[1][1]='A';a[1][2]='B';a[1][3]='C';//转化成二维数组
    a[2][1]='D';a[2][2]='E';a[2][3]='*';
    dfs(2,3);
}
int main(){
    solve();//预处理出所有终点能到的状态,只要终点能到,那么它也可以到终点。
    int t;cin>>t;
    for(int i=1;i<=t;i++){
        if(t==1) cout<<1<<endl;
        else cout<<mp[check()]<<endl;
    }
}

题外话:

1.这道题官方数据出锅啦,只要输出1就能过。

2.这道题的背景应该是“八数码”,“八数码”是一个求给定状态到目的状态的最少操作次数,操作也是移动某个特定格子。

标签:状态,终点,ty,int,字母,bfs,Day3,dfs,蓝桥
From: https://www.cnblogs.com/liyishui2003/p/18063576

相关文章

  • 蓝桥杯-地宫取宝
    这是一个dp题,可以用4维数据来表示所有的状态。但是有一个需要注意的点,一般来说,对于每个坐标,有拿跟不拿两种情况,如果没有拿任务宝物的状态表示为0,那么拿取了价值为0的宝物时,要以另一种情况来跟没拿区分。处理的方法就是将所有宝物的价格+1。longlongdp[55][55][15][15];const......
  • 【蓝桥-大试牛刀7-最短路专场】一点提示
    最短路1求个全源最短路。看数据范围\(1\len\le100\),直接floyd秒掉就行。最短路2先判负环,用Bellman-Ford,当然建议用队列优化版的(国内一般叫spfa)。虽然说spfa复杂度不稳定,但也一定比朴素版要快一点的。第二步还是求全源最短路,但是这个题的数据范围到了\(1\len\le3\times10^3......
  • [蓝桥杯 2019 省 B] 后缀表达式
    这题没想到怎么贪心,看题解恍然大明白#include<iostream>#include<stdio.h>#include<algorithm>#include<string>#defineFor(i,j,n)for(inti=j;i<=n;++i)usingnamespacestd;typedeflonglongLL;constintN=2e5+5;LLans;in......
  • [蓝桥杯 2019 省 B] 等差数列
    实际上这道题不需要先排序再求gcd,因为无论是哪两项之前作差,都不会影响最后的gcd的结果。因为公差是从a2-a1开始算的,因此i=1时要特殊处理,不能把a1-0计入贡献,否则会算出错误的gcd。即作差时不要加上a1-0,统计最值时不要漏掉a1#include<iostream>#include<stdio.h>#include<a......
  • DSP笔记[2]-数码管显示英文字母及在flash上运行
    摘要在TMS320F28335开发板上实现8位数码管显示英文字母及烧录程序到Flash中断电程序不丢失;矩阵键盘扫描,实现按键1清零,按键2累加,按键3显示字母,按键4显示数字,按键5开关LED灯;LED流水灯.关键信息系统:macOS13.5(AppleSiliconM2)(烧录)系统:windows11(arm64)(编译)......
  • 中考英语首字母快速突破001-2021上海宝山英语二模
    PDF格式公众号回复关键字:ZKSZM001原文Whatislaughter?Laughterisnaturalforpeople.Westarttolaughataboutfourmonthsofage.Westarttolaughevenbeforewestarttospeak!Laughterissocial.Itconnectsuswithotherpeople.Welaughmorewhenw......
  • Java蓝桥杯题目——1264排个序
    题目 思路:1、输入数据2、用冒泡排序将数组(下标为pj的)部分升序,3、判断是否有前一个元素大于后一个元素(降序),有则返回false注意:(1)数组p元素的取值不能大于数组a的长度,因为p元素是a的下标(2)数组下标越界问题,使用i<a.length判断(3)并非所有元素都要降序才返回false,只要有前一个元......
  • 每天一道蓝桥杯 Day2 翻转+阶乘求和
    阶乘求和 只要后9位的话,那就只考虑后9位!如何只算后9位?有一个很经典的运算:取模。回想入门c语言时做过一道题,给定三位数,要求进行数字翻转。比如给定n,n=123,要翻转成321。一个做法是令a1=n%10,a2=(n%100)/10,a3=n/100输出a1*100+a2*10+a3即可。所以遇到求一个很大的值除以某数......
  • P8630 [蓝桥杯 2015 国 B] 密文搜索
    网站:https://www.luogu.com.cn/problem/P8630代码如下:主要是用了map的思想#include<iostream>#include<vector>#include<algorithm>#include<math.h>#include<string>#include<string.h>#include<iomanip>#include<map>#incl......
  • 17. 电话号码的字母组合c
    C语言字符串细节真多啊,搞了好久。/***Note:Thereturnedarraymustbemalloced,assumecallercallsfree().*/charc[10][5]={"","","abc","def","ghi","jkl","mno","pqrs","tuv"......