网易2019暑期实习笔试

版权声明:本文为博主原创文章,欢迎转载!转载请保留原博客地址。 https://blog.csdn.net/grllery/article/details/88384918

网易笔试

题目: 有一个特殊的键盘,只有a-zshift共27个按键。其中点击会字母按钮会输出对应的字母,该键盘还有一些特殊的规则:可以通过shift键搭配一个字母输出另一个字母。例如你可以通过shift+a输出b,并且这个输入时支持递归的,即shift+shift+a等同于输入shift+b
现在这个键盘有一部分是失灵的,面对堆积如山的稿子,你想知道这个键盘能否完成接下来的工作?如果可以,每篇稿子需要点击多少次按键?

分析:根据图论的思想,计算所有点到损坏按键的最小路径。难点在于怎么构建对应邻接矩阵的权值,然后根据邻接矩阵采用Floyd方法。代码只测试了给的示例,未完全测试。
在这里插入图片描述
在这里插入图片描述

26个字母建图,自己到自己是0,shift+a到b就是b到a有一条权值1的边,坏掉的键自己到自己是inf,然后每个字母跑一次dij,所有自环不是inf的点里到它距离最近的距离,就是这个字母的最小花费。最后直接处理文本,碰到花费inf的就是-1,否则输出总花费+串长。参见Techiah

#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<limits>
using namespace std;
#define INF 1000

void floyd(vector<vector<int>>& adjacency_matrix, vector<vector<int>>& path) {
    int cnt = adjacency_matrix.size();
    //并入每个节点
    for (int k = 0; k < cnt; ++k) {
    for (int i = 0; i < cnt; ++i) {
        for (int j = 0; j < cnt; ++j) {
        if (adjacency_matrix[i][k] + adjacency_matrix[k][j] < adjacency_matrix[i][j]) {
            adjacency_matrix[i][j] = adjacency_matrix[i][k] + adjacency_matrix[k][j];
            path[i][j] = adjacency_matrix[i][k];
        }
        }
    }
    }
    return;
}

int main()
{
    int example;
    cin >> example;
    while (example > 0) {
        --example;
        vector<vector<int>> matrix(26, vector<int>(26, INF)); //构建邻接矩阵
        for (int i = 0; i < 26; ++i)
            matrix[i][i] = 0;  //初始化每个按键均为好的,自己到自己的权重为0

        int num;
        cin >> num;
        char c, d;
        while (num > 0 && cin >> c >> d) {
            --num;
            matrix[c - 'a'][d - 'a'] = 1;  //更新有shift规则的按键的权重
        }

        cin >> num;
        vector<int> bad_key;
        while (num > 0 && cin >> c) {
            --num;
            matrix[c - 'a'][c - 'a'] = INF;  //更新损坏的按键的权重
            bad_key.push_back(c - 'a');
        }

        //floyd
        vector<vector<int>> path(matrix);
        floyd(matrix, path);

        //计算到每个按键的最短路径
        int min_path[26];    //注意: int min_path[26] = { INF };  {INF, 0, 0, 0......}
        for (int i = 0; i < 26; ++i) {
            min_path[i] = INF;
            for (int j = 0; j < 26; ++j) {
            //注意最短路径计算时只能从未损坏的键到26个键
            if (find(bad_key.begin(), bad_key.end(), j) != bad_key.end())
                continue;
            min_path[i] = min(min_path[i], matrix[j][i]);
            }
        }

        string s;
        cin >> s;
        int res = s.size();
        for (auto c : s) {
            //如果到某个按键的最短路径为INF,则表明没有路径能到达,输出-1
            if (min_path[c - 'a'] == INF) {
            cout << -1 << endl;
            return 0;
            }
            res += min_path[c - 'a'];
        }
        cout << res << endl;
    }
}

3
5
a b
b c
x c
e f
f x
2
b c
helloworldabc
5
a b
b c
x c
e f
f x
4
b c f x
helloworldabcsfx
5
a b
b c
x c
e f
f x
4
b c f g
helloworldabcsfg

猜你喜欢

转载自blog.csdn.net/grllery/article/details/88384918