【周赛第69期】满分题解 软件工程选择题 枚举 dfs

昨晚没睡好,脑子不清醒,痛失第1名

选择题

1.

关于工程效能,以下哪个选项可以帮助提高团队的开发效率?
A、频繁地进行代码审查
B、使用自动化测试工具
C、使用版本控制系统
D、所有选项都正确

选D。

2.

以下哪个选项不属于编码规范的内容?
A、变量命名规则
B、注释规范
C、代码缩进和格式化
D、数据库表设计

选D。

3.

以下哪个设计原则鼓励我们在实现功能时,尽量对现有代码进行扩展而不是修改?
A、单一职责原则
B、开放封闭原则
C、里氏替换原则
D、接口隔离原则

选B。

4.

关于软件架构设计,以下哪个原则可以帮助我们降低系统的耦合度?
A、单一职责原则
B、开放封闭原则
C、里氏替换原则
D、依赖倒置原则

选D。

面向对象设计七大原则

开闭原则、里氏代换原则、迪米特原则(最少知道原则)、单一职责原则、接口分隔原则、依赖倒置原则、组合/聚合复用原则。

编程题

S数

如果一个正整数 自身是回文数 ,而且它也是一个 回文数平方,那么我们称这个数为 S数。 现在,给定两个正整数
L 和 R(以字符串形式表示),返回包含在范围 [L, R] 中的S数的数目。

我是按自身是回文数枚举的,其实应该按枚举量少的进行枚举,按开平方后的回文数枚举应该会更快。
为了代码简单写的快最后再检查范围。

#include<bits/stdc++.h>

using namespace std;
using LL = long long;
LL L, R;
int strL[20], strR[20];
int topL, topR;
LL ans = 0;
int str[20];

bool check(int x) {
    int s[20] = {};
    int len = 0;
    while (x) {
        s[++len] = x % 10;
        x /= 10;
    }
    for (int i = 1, j = len; i < j; i++, j--) {
        if (s[i] != s[j])
            return false;
    }
    return true;
}

void dfs(LL now, int step, int base, int len) {
    if (step == base + 1) {
        if (len & 1) {
            for (int i = base - 1; i >= 1; i--) {
                now = now * 10 + str[i];
            }
        } else {
            for (int i = base; i >= 1; i--) {
                now = now * 10 + str[i];
            }
        }
        if (now < L)
            return;
        if (now > R) {
            cout << ans << endl;
            exit(0);
        }
        LL tmp = sqrt(now);
        if (tmp * tmp == now && check(tmp)) {
            ++ans;
        }
        if ((tmp + 1) * (tmp + 1) == now && check(tmp + 1)) {
            //cout<<" "<<now<<endl;
            ++ans;
        }
        return;
    }
    if (step == 1) {
        static const int f[] = {0, 1, 4, 5, 6, 9};
        for (int i = 0; i < 6; i++) {
            str[step] = f[i];
            dfs(now * 10 + f[i], step + 1, base, len);
        }
    } else {
        for (int i = 0; i <= 9; i++) {
            str[step] = i;
            dfs(now * 10 + i, step + 1, base, len);
        }
    }
}

int main() {
    cin >> L >> R;
    for (int i = L; i; i /= 10) {
        strL[++topL] = i % 10;
    }
    for (int i = R; i; i /= 10) {
        strR[++topR] = i % 10;
    }
    for (int len = topL; len <= topR; len++) {
        int baseLen = (len + 1) / 2;
        dfs(0, 1, baseLen, len);
    }
    cout << ans << endl;
    return 0;
}

最小H值

给你一个二维 rows x columns 的地图 heights , 其中 heights[row][col] 表示格子 (row,
col) 的高度。 一开始你在最左上角的格子 (0, 0) , 且你希望去最右下角的格子 (rows-1, columns-1)
(注意下标从 0 开始编号)。 你每次可以往 上,下,左,右 四个方向之一移动,你想要找到H值最小的一条路径。 一条路径的 H值
是路径上相邻格子之间 高度差绝对值最大值 决定的。 请你返回从左上角走到右下角的最小H值。

不是只能下、右,一开始想错了。
dfs需要注意避免不必要的重复,才能保证时间复杂度。

#include<bits/stdc++.h>

using namespace std;
string mp;
int hang = -1;
int lie = 1;
vector<vector<int>> mpp;
vector<vector<int>> dis;

inline char getChar() {
    static int pos = 0;
    if (pos == (int) mp.length()) {
        return EOF;
    }
    return mp[pos++];
}

inline int getInt() {
    int x = 0;
    int f = 1;
    char t = getChar();
    while (t > '9' || t < '0') {
        if (t == '-')f = -1;
        t = getChar();
    }
    while (t >= '0' && t <= '9') {
        x = x * 10 + t - '0';
        t = getChar();
    }
    return x * f;
}

const int f[4][2] = {{-1, 0},
                     {0,  -1},
                     {0,  1},
                     {1,  0}};

bool dfs(int x, int y) {
    if (x == hang - 1 && y == lie - 1) {
        return true;
    }
    for (int i = 0; i < 4; i++) {
        int nx = x + f[i][0];
        int ny = y + f[i][1];
        if (nx < 0 || ny < 0 || nx >= hang || ny >= lie) { continue; }
        int newDis = max(dis[x][y], abs(mpp[x][y] - mpp[nx][ny]));
        if (dis[nx][ny] != -1 && dis[nx][ny] <= newDis) { continue; }
        dis[nx][ny] = newDis;
        //cout<<nx<<" "<<ny<<" : "<<newDis<<endl;
        dfs(nx, ny);
    }
    return true;
}

int main() {
    cin >> mp;
    for (int i = 0; i < (int) mp.length(); i++) { if (mp[i] == '[') { ++hang; }}
    for (int i = 0; i < (int) mp.length(); i++) {
        if (mp[i] == ']') { break; }
        if (mp[i] == ',') { ++lie; }
    }
    mpp = vector<vector<int>>(hang, vector<int>(lie, 0));
    vector<vector<int>> dp = vector<vector<int>>(hang, vector<int>(lie, 0));
    dis = vector<vector<int>>(hang, vector<int>(lie, -1));
    for (int nowH = 0, nowL = 0; nowH <
                                 hang;) {
        mpp[nowH][nowL] = getInt();
        //cout<<nowH<<" "<<nowL<<" : "<<mpp[nowH][nowL]<<endl;
        ++nowL;
        if (nowL == lie) {
            ++nowH;
            nowL = 0;
        }
    }
    for (int i = 0; i < hang; i++) {
        for (int j = 0; j < lie; j++) {
            if (i == 0 && j == 0) {
                dp[i][j] = 0;
            } else if (i == 0) {
                dp[i][j] = max(dp[i][j - 1], abs(mpp[i][j] - mpp[i][j - 1]));
            } else if (j == 0) {
                dp[i][j] = max(dp[i - 1][j], abs(mpp[i][j] - mpp[i - 1][j]));
            } else {
                dp[i][j] = min(max(dp[i][j - 1], abs(mpp[i][j] - mpp[i][j - 1])),
                               max(dp[i - 1][j], abs(mpp[i][j] - mpp[i - 1][j])));
            }
        }
    }
    dis[0][0] = 0;
    dfs(0, 0);
    cout << dis[hang - 1][lie - 1] << endl;
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值