例题1
https://leetcode-cn.com/problems/perfect-squares/
描述
Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...
) which sum to n.
Example 1:
Input: n =12
Output: 3 Explanation:12 = 4 + 4 + 4.
Example 2:
Input: n =13
Output: 2 Explanation:13 = 4 + 9.
解析
class Solution {
public:
unordered_set<int> sett;
int numSquares(int n) {
queue<int> q;
q.push(0);
int step=0;
while(!q.empty()){
step++;
int cnt=q.size();
while(cnt--){ //逐层入队
int num=q.front();
q.pop();
for(int i=1;i*i<=n-num;i++){
int a=num+i*i;
if(a>n) break;
if(a==n) return step;
if(sett.count(a)==0){ //剪枝
q.push(a); //将平方数的和入队以保存状态
sett.insert(a);
}
}
}
}
return 0;
}
};
例题2
https://www.luogu.com.cn/problem/P1032
题目描述
解析
BFS:每次取出队首元素,对其按规则进行转换,将所有可能的转换结果都入队。可以通过将已经入队过的字符串加入到hashset中,入队时不用将已经入队过的字符串再入队(因为前面已经入队过了,再入队也不可能比前面一个更快地到达目标字符串),这就是一种“剪枝”。
这题有一个坑就是慎用size()-size(),具体见文章:这里
#include<iostream>
#include<string>
#include<vector>
#include<unordered_set>
#include<map>
#include<queue>
using namespace std;
unordered_set<string> sett;
vector<pair<string, string>> v;
queue<string> q;
int main() {
//freopen("1.txt", "r", stdin);
string a, b, ta, tb;
cin >> a >> b;
while (cin >> ta >> tb) {
v.push_back({ ta,tb });
}
q.push(a);
sett.insert(a);
int step = 0;
while (!q.empty() && step < 10) {
int cnt = q.size();
while (cnt--) {
string now = q.front(); q.pop();
if (now == b) {
printf("%d", step);
return 0;
}
for (auto it : v) {
string s1 = it.first, s2 = it.second, next;
if (now.size() < s1.size()) continue; //注意这里
for (int i = 0; i <= now.size() - s1.size(); i++) {
auto pos = now.find(s1, i);
if (pos != string::npos) {
next = now;
next.replace(pos, s1.size(), s2);
if (!sett.count(next)) {
q.push(next);
sett.insert(next);
}
}
}
}
}
step++;
}
printf("NO ANSWER!");
return 0;
}