• 蓝桥ACM培训-搜索


    前言:

       今老师讲了了dfs,虽然我自己之前也自学了一点点,但我还是感觉做题并不是很顺,尤其是今天最后一题,我调试了一下午都没过,还需要积累经验呀。

    正文:

    Problem:A 白与黑-搜索:

    1. #include
    2. using namespace std;
    3. int n,m,sum,newx,newy;
    4. string a[101];
    5. int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
    6. int dfs(int x,int y)
    7. {
    8. a[x][y]='#';
    9. for(int i=0;i<4;i++)
    10. {
    11. newx=x+dir[i][0];
    12. newy=y+dir[i][1];
    13. if(newx>=0&&newx=0&&newy'#')
    14. sum++,dfs(newx,newy);
    15. }
    16. // for(int i=1;i<=9;i++){
    17. // for(int o=1;o<=6;o++){
    18. // cout<
    19. // }
    20. // cout<
    21. // }
    22. }
    23. int main()
    24. {
    25. while(cin>>n>>m&&n&&m)
    26. {
    27. for(int i=0;i
    28. cin>>a[i];
    29. sum=1;
    30. for(int i=0;i
    31. for(int j=0;j
    32. if(a[i][j]=='@')dfs(i,j);
    33. cout<
    34. }
    35. return 0;
    36. }

    这道题其实是很经典的红与黑问题,在@处开始dfs去搜寻全部可行点并切不需要回溯(不需要回复已标记点)。

    Problem:B 迷宫寻路-搜索:

    1. #include
    2. using namespace std;
    3. int n,m;
    4. int stx,sty,enx,eny;
    5. string a[1005];
    6. int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
    7. void dfs(int x,int y)
    8. {
    9. a[x][y]='#';
    10. for(int i=0;i<4;i++)
    11. {
    12. int newx=x+dir[i][0];
    13. int newy=y+dir[i][1];
    14. if(newx>=0 && newx=0 && newy'*')
    15. {
    16. dfs(newx,newy);
    17. }
    18. }
    19. }
    20. int main()
    21. {
    22. while(scanf("%d%d",&n,&m)!=-1)
    23. {
    24. stx=sty=enx=eny=-1;
    25. for(int i=0;i>a[i];
    26. for(int i=0;i
    27. for(int j=0;j
    28. {
    29. if((i==0 || i==n-1 || j==0 || j==m-1) && a[i][j]=='*')
    30. {
    31. if(stx==-1) stx=i,sty=j;
    32. else enx=i,eny=j;
    33. }
    34. }
    35. dfs(stx,sty);
    36. if(a[enx][eny]!='#') printf("NO\n");
    37. else printf("YES\n");
    38. }
    39. }

    找到两个边沿的起点在从一个出发开始dfs,标记所有搜到的点,最后看看另一个起点是否被标记即可。

    Problem:C 猴群-搜索:

    1. #include
    2. using namespace std;
    3. int n,m;
    4. int num;
    5. string a[105];
    6. int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
    7. int dfs(int x,int y)
    8. {
    9. a[x][y]='0';
    10. for(int i=0;i
    11. {
    12. int newx=x+dir[i][0];
    13. int newy=y+dir[i][1];
    14. if(newx>=0 && newx=0 && newy'0')
    15. {
    16. dfs(newx,newy);
    17. }
    18. }
    19. }
    20. int main()
    21. {
    22. scanf("%d%d",&n,&m);
    23. num=0;
    24. for(int i=0;i>a[i];
    25. for(int i=0;i
    26. {
    27. for(int j=0;j
    28. {
    29. if(a[i][j]!='0')
    30. {
    31. num++;
    32. dfs(i,j);
    33. }
    34. }
    35. }
    36. printf("%d\n",num);
    37. }

    老师专门讲了这个题,我们只需从头遍历到尾去找非0值,找到后答案加1,并从该点出发搜寻相邻的全部非0值,将他们更新为0,在继续遍历即可。

    Problem:D 01迷宫-搜索:

    1. #include
    2. using namespace std;
    3. char mp[1009][1009];
    4. int n,m,fx,fy,tx,ty,cnt;
    5. int book[1009][1009],ans[100009],dis[1009][1009];
    6. int nx[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
    7. void dfs(int x,int y){
    8. //cout<
    9. book[x][y]=1;
    10. dis[x][y]=cnt;ans[cnt]++;
    11. for(int i=0;i<=3;i++){
    12. tx=x+nx[i][0];ty=y+nx[i][1];
    13. if(tx<1||tx>n||ty<1||ty>n||mp[tx][ty]==mp[x][y]||book[tx][ty]==1)continue;
    14. dfs(tx,ty);
    15. }
    16. //return;
    17. }
    18. int main(){
    19. ios::sync_with_stdio(false);
    20. cin>>n>>m;
    21. for(int i=1;i<=n;i++){
    22. for(int o=1;o<=n;o++){
    23. cin>>mp[i][o];
    24. }
    25. }
    26. cnt=1;
    27. while(m--){
    28. cin>>fx>>fy;
    29. if(dis[fx][fy]==0){cnt++;dfs(fx,fy);cout<
    30. else cout<
    31. }
    32. return 0;
    33. }

    这题是洛谷的1141题,在 oj上更新过数据,我不知道老师加了个什么数据进去,反正我优化了一下午代码,洛谷上都过了,在林大oj上还是TLE,心态炸了。这题和以往题差不多,但为了优化时间我们在搜索时标记一下,下次搜索时就不用在找一次了,听说用记忆化搜索可以过,等我这几天去了解一下,之后看看能不能过。

    后记:

       今天这个是开始训练以来最难以理解的一个算法了,不过之后肯定还有更加抽象的等着我,好好努力吧。

  • 相关阅读:
    只需3步,用华为云CodeArts快速搭建一个网上商城
    三入职场!你可以从我身上学到这些(附毕业Vlog)
    微服务治理热门技术揭秘:无损上线
    云原生周刊:KubeSphere 3.4.1 发布 | 2023.11.13
    信创之国产浪潮电脑+统信UOS操作系统体验4:visual studio code中怎么显示中文
    字符串——子串查找(kmp)
    c# 字符串格式化日期时间
    二零二四:不要再当差一点先生
    Java架构师分布式搜索数据迁移
    Win11任务栏怎么靠左显示?
  • 原文地址:https://blog.csdn.net/Wzh20060111/article/details/136418893