试题 算法提高 Channel

资源限制

时间限制:1.0s 内存限制:256.0MB

问题描述

Joe,一个前冠军程序员,终于买了农场。不,不,他过得很好;他只是利用了他丰富的编程比赛奖金购买了他的祖传农场。
  他希望退休,养奶牛度过余生(因为一些原因,他现在认为自己是一个奶牛专家)。
  不幸的是,农夫Joe简单的田园梦也无法实现。他的农场所在气候寒冷–对于奶牛太冷了!
  更糟糕的是,气候很干燥不适合种植庄稼。Joe现在意识到他必须为自己的农场制定一个灌溉方案。这个方案将使一条河穿过农场里的一条蜿蜒的渠道。由于作物在渠道旁能茁壮成长,所以渠道越长越好。
  他的田地是一个被划分成格子的狭长的矩形。一些格子有泥土,用".“表示,或者不能移动的石头,用”#"表示。灌溉渠道是一个一格宽的从田地左上角进入从右下角流出。石头的格子不能通过。当然,它不能够自交,即使是在角上碰到也不行(这样水会渗透并采取更短的路径)。
  下面两种情况表示渠道自交:
  CCCC C…
  C.C.C CCCC
  CCC.C …CC
  …CC …C.
  …C. …C.
  …CC …CC
  (为什么不能等宽,大家自行放到等宽字体中看吧)
  不幸的是,Joe那最好的编程能力已经被他抛之脑后了。他有一个很简单的解决方法但是太耗时了。你能帮他找到这个渠道的最佳位置吗?

输入格式

输入包含多组数据。
  每个测试数据包含一个r表示行数(2<=r<=20)和一个c表示列数(2<=c<=9)。接着r行c列的一个矩阵表示他的田地。
  由0 0结束输入
输出格式
  对于每一组数据。
  输出数据序号。
  接下来r行表示一种设置渠道的方案,保证有解。
  每组数据后输出一个空行。
  参照样例。

样例输入

样例输出

在这里插入图片描述

数据规模和约定

见输入格式。

思路

这一题有提示是使用插头dp 状压dp 动态规划的方法。但博主还是比较菜的,这个算法思想没有具体用过,一时半会想不出来,等我问问大佬再更新一波。
所以这一题使用的是迷宫问题的解法,只需要遍历完每一个情况就可以,每个回退的情况都要考虑,因此,最后提交的时候还是扣了5分,因为超时了……
说说我的思路吧,因为是骗分蓝桥,扣5分还好。进入一个循环,直到开始的点的每一个情况都考虑完为止,这时候栈内元素为空,所以条件就是栈为空就可以输出了,其他就是迷宫问题的常用方法来解决,进行对应的压栈出栈操作,不过这一题的情况条件会加的比较多,考虑边界和不能相交的多种情况来解决这一个问题。

有些问题的代码

#include<bits/stdc++.h>
using namespace std;
int main() {
    string a[25];
    char a1[25][15];
    int x, y;
    stack<int> s;
    while (cin>>x>>y) {
        if (x == 0 && y == 0)break;
        for (int i = 1; i <= x; i++) {
            a[i] = " ";
            string s;
            cin >> s;
            a[i] += s;
        }
        int l = 0;
        int x1 = 1, y1 = 1;
        int m = 0;
        int k = 0;
        int max = 0, c = 0;
        while (!l) {
            if (k) {
                switch (m) {
                case 1:a[x1][y1--]='.'; break;
                case 2:a[x1--][y1]='.'; break;
                case 3:a[x1][y1++]='.'; break;
                case 4:a[x1++][y1]='.'; break;
                }
                k = 0;
                c--;
            }
            m++;
            switch (m) {
            case 1:if (y1!=y&&a[x1][y1+1] == '.' && (y1 + 2 == y+1 || a[x1][y1 + 2] != 'C') && (x1 - 1 == 0 || a[x1 - 1][y1 + 1] != 'C') && (x1 == x || a[x1 + 1][y1 + 1] != 'C')) {
                a[x1][y1++]='C';
                c++;
                s.push(1);
                m = 0;
                break;
            }
            case 2:if (x1 != x &&a[x1+1][y1] == '.' && (x1 + 2 == x+1 || a[x1+2][y1] != 'C') && (y1 - 1 == 0 || a[x1 + 1][y1 - 1] != 'C') && (y1 == y || a[x1 + 1][y1 + 1] != 'C')) {
                a[x1++][y1] = 'C';
                c++;
                s.push(2);
                m = 0;
                break;
            }
            case 3:if (y1 != 1 && a[x1][y1-1] == '.' && (y1 - 2 == 0 || a[x1][y1 - 2] != 'C') && (x1 - 1 == 0 || a[x1 - 1][y1 - 1] != 'C') && (x1 == x || a[x1 + 1][y1 - 1] != 'C')) {
                a[x1][y1--] = 'C';
                c++;
                s.push(3);
                m = 0;
                break;
            }
            case 4:if (x1 != 1 && a[x1-1][y1] == '.' && (x1 - 2 == 0 || a[x1-2][y1] != 'C') && (y1 - 1 == 0 || a[x1 - 1][y1 - 1] != 'C') && (y1  == y || a[x1 - 1][y1 + 1] != 'C')) {
                a[x1--][y1] = 'C';
                c++;
                s.push(4);
                m = 0;
                break;
            }
            case 5:
                if (!s.empty()) {
                    m = s.top();
                    s.pop();
                    k = 1;
                }
                else {
                    l = 1;
                }
            }
            if (max < c && x1 == x  && y1 == y ) {
                max = c;
                for (int i = 1; i <= x; i++) {
                    for (int j = 1; j <= y; j++) {
                        a1[i][j] = a[i][j];
                    }
                }
            }
        }
        a1[x ][y ] = 'C';
        for (int i = 1; i <= x; i++) {
            for (int j = 1; j <= y; j++) {
                cout << a1[i][j];
            }
            cout << endl;
        }
        cout << endl;
    }
    return 0;
}

结果

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值