1.回环句
回环句
Solution
class Solution {
public:
bool isCircularSentence(string sentence) {
int n = sentence.size(), i = 0;
if (sentence[0] != sentence[n - 1]) return false;
for (int i = 0; i < n; i++) {
if (sentence[i] == ' ' && sentence[i - 1] != sentence[i + 1])
return false;
}
return true;
}
};
2.划分技能点相等的团队
划分技能点相等的团队
Solution
class Solution {
public:
long long dividePlayers(vector<int>& skill) {
long long sum = accumulate(skill.begin(),skill.end(),0);
int n = skill.size() / 2;
long long t = sum / n;
if(sum % n != 0) return -1;
sort(skill.begin(),skill.end());
long long ans = 0;
vector<long long> book(1005,0);
for(int i = 0;i < skill.size();i++){
int p = skill[i];
book[p]++;
}
for(int i = 0;i < n;i++){
long long p = skill[i];
if(book[t - p] == 0){
return -1;
}
ans += (long long)(p * (t - p));
book[p]--;
book[t - p]--;
}
return ans;
}
};
3.两个城市间路径的最小分数
两个城市间路径的最小分数
Solution
class Solution {
public:
int minScore(int n, vector<vector<int>>& roads) {
//建图
vector<int> e[n+1], v[n+1];
for(auto road : roads){
e[road[0]].push_back(road[1]);
v[road[0]].push_back(road[2]);
e[road[1]].push_back(road[0]);
v[road[1]].push_back(road[2]);
}
int ans = INT_MAX;
queue<int>q;
bool vis[n+1];
memset(vis,0,sizeof(vis));
q.push(1),vis[1] = true;
while(!q.empty()){
int sn = q.front();q.pop();
for (int i = 0; i < e[sn].size(); i++) {
// 枚举连接 sn 的所有边并更新答案
ans = min(ans, v[sn][i]);
int fn = e[sn][i];
if (vis[fn]) continue;
q.push(fn); vis[fn] = true;
}
}
return ans;
}
};
4.将节点分成尽可能多的组
将节点分成尽可能多的组
Solution
class Solution {
public:
int magnificentSets(int n, vector<vector<int>>& edges) {
vector<int> e[n + 1];
for (auto &edge : edges) {
e[edge[0]].push_back(edge[1]);
e[edge[1]].push_back(edge[0]);
}
// mp[i] 表示 i 代表的连通块的答案
unordered_map<int, int> mp;
// 以 S 作为 BFS 的起点
// 以连通块中编号最小的点 mn 为代表
// 把这个连通块的解记到 mp[mn] 里
auto bfs = [&](int S) {
int mn = S;
queue<int> q;
int dis[n + 1];
memset(dis, 0, sizeof(dis));
q.push(S); dis[S] = 1;
while (!q.empty()) {
int sn = q.front(); q.pop();
mn = min(mn, sn);
for (int fn : e[sn]) {
if (dis[fn]) continue;
q.push(fn);
dis[fn] = dis[sn] + 1;
}
}
int &ret = mp[mn];
// 检查分组的合法性
for (int i = 1; i <= n; i++) if (dis[i]) for (int fn : e[i]) if (abs(dis[i] - dis[fn]) != 1) return;
// 求最大距离
for (int i = 1; i <= n; i++) if (dis[i]) ret = max(ret, dis[i]);
};
// 枚举以每个点作为 BFS 的起点,并更新所属连通块的答案
for (int i = 1; i <= n; i++) bfs(i);
int ans = 0;
// 枚举所有连通块
for (auto it = mp.begin(); it != mp.end(); it++) {
// 只要有一个连通块无解就无解
if (it->second == 0) return -1;
// 否则答案就是所有连通块的解的总和
ans += it->second;
}
return ans;
}
};