- 110. 字符串迁移
和前面二维数组保存的图本质上其实是相同的,前面的题用二维数组保存节点的关系,本题使用set来保存,通过检查是否在set中来看是不是能够相连;前面的题遍历时是按照上下左右走,本题就是按照26个小写字母来替换每一位
#include <iostream>
#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
int main() {
unordered_set<string> words;
int n = 0;
cin >> n;
string beginStr, endStr;
cin >> beginStr >> endStr;
string word;
for (int i = 0; i < n; i++) {
cin >> word;
words.insert(word);
}
unordered_map<string, int> visited;
queue<string> q;
visited.emplace(beginStr, 1);
q.push(beginStr);
while (!q.empty()) {
word = q.front();
q.pop();
for (int i = 0; i < word.size(); ++i) {
string newword = word;
for (int j = 0; j < 26; ++j) {
newword[i] = j + 'a';
if (newword == endStr) {
cout << visited[word] + 1 << endl;
return 0;
}
if (words.find(newword) != words.end() &&
visited.find(newword) == visited.end()) {
visited.emplace(newword, visited[word] + 1);
q.push(newword);
}
}
}
}
cout << 0 << endl;
return 0;
}
- 105. 有向图的完全联通
从1开始遍历索引可达节点,记录个数,如果可达节点数等于n,那么就代表1可以到达所有节点
#include <iostream>
#include <list>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
class EdgeNode {
public:
EdgeNode() { next = -1; }
EdgeNode(int next) { this->next = next; }
const int GetNext() { return next; }
private:
int next;
};
class MyGraph {
public:
MyGraph() {}
MyGraph(int n_vertex) {
vertexes = vector<int>(n_vertex);
for (int i = 1; i <= n_vertex; i++) {
vertexes[i - 1] = i;
}
}
void AddVertex(int vertex) { vertexes.push_back(vertex); }
void AddEdge(int from, int to) {
if (edges.find(from) == edges.end()) {
edges[from] = list<EdgeNode *>();
}
edges[from].push_back(new EdgeNode(to));
}
~MyGraph() {
for (auto item : edges) {
for (EdgeNode *edge : item.second) {
delete edge;
}
}
}
list<EdgeNode *> GetEdges(int vertex) { return edges[vertex]; }
void dfs(int beginVertex, vector<bool> &visited, int &count) {
auto edge = edges[beginVertex];
for (auto e : edge) {
if (!visited[e->GetNext()]) {
count++;
visited[e->GetNext()] = true;
dfs(e->GetNext(), visited, count);
}
}
}
private:
vector<int> vertexes;
unordered_map<int, list<EdgeNode *>> edges;
};
int main() {
int n = 0, m = 0;
cin >> n >> m;
MyGraph graph(n);
int from = 0, to = 0;
for (int i = 0; i < m; i++) {
cin >> from >> to;
graph.AddEdge(from, to);
}
int count = 1;
vector<bool> visited(n + 1);
visited[1] = true;
graph.dfs(1, visited, count);
cout << (count == n ? 1 : -1) << endl;
return 0;
}
- [106. 海岸线计算]](kamacoder.com/problempage…)
找海岸线,就是找每一个陆地,也就是值为1的点周围的海水节点,也就是值为0的节点的个数;海水节点不用记录是否访问过,因为一块海水可能被多个陆地包围;另外,题目假设矩阵外均被水包围,因此我们设置数组的大小为n+2与m+2。
#include <iostream>
#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
void dfs(vector<vector<int>> &grid, vector<vector<bool>> &visited, int i, int j,
int &count) {
for (auto d : dir) {
int next_i = i + d[0];
int next_j = j + d[1];
if (next_i < 0 || next_i >= grid.size() || next_j < 0 ||
next_j >= grid[0].size()) {
continue;
}
if (grid[next_i][next_j] == 0) {
count++;
}
if (!visited[next_i][next_j] && grid[next_i][next_j] == 1) {
visited[next_i][next_j] = true;
dfs(grid, visited, next_i, next_j, count);
}
}
}
int main() {
int n, m;
cin >> n >> m;
vector<vector<int>> grid(n + 2, vector<int>(m + 2, 0));
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
cin >> grid[i][j];
}
}
vector<vector<bool>> visited(n + 2, vector<bool>(m + 2));
int count = 0;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
if (grid[i][j] == 1) {
visited[i][j] = true;
dfs(grid, visited, i, j, count);
cout << count << endl;
return 0;
}
}
}
return 0;
}