一. 题目
(1)早安
思路:
(1)cin和scanf读入字符串时遇到空格或换行就停止读入,对于要读入带空格的字符串时,常用 两种方法:
// 法一
string s;
getline( cin, s );
// 法二
char s [ 1005 ];
gets(str);
// 获取读入长度
int len = strlen( s );
(2)因为是子串,注意 ' good morning ' 首尾都是g,因此只有第一个 ' good morning ' 要用两个 ' g ' ,后面每个都只要用一个 ' g ' 。
(3)空格也要统计,每一个 ' good morning ' 都需要一个空格
(4)如果先读入一个数字,再接着读入字符串时,需要在读入数字后加上 ' getchar() ' ,用来吃掉回车,否则回车也将当做是一个字符加入到后面的字符串中。
代码:
#include<bits/stdc++.h>
#define LL long long
using namespace std;
int n, t, ng, no, nd, nm, nr, nn, ni, nk, ans;
string s;
int main()
{
cin >> t;
getchar();
while (t --)
{
ng = 0, no = 0, nd = 0, nm = 0, nr = 0, nn = 0, ni = 0, nk = 0;
getline(cin,str);
for (int i = 0; i < s.length(); i ++)
{
if (str[i] == 'g') ng ++;
if (str[i] == 'o') no ++;
if (str[i] == 'd') nd ++;
if (str[i] == 'm') nm ++;
if (str[i] == 'r') nr ++;
if (str[i] == 'n') nn ++;
if (str[i] == 'i') ni ++;
if (str[i] == ' ') nk ++;
}
ng --;
no /= 3, nn /= 2;
ans = min( min( min(ng, no), min(nd, nm) ), min(nr, nn) );
ans = min(min(ans, ni), nk);
cout << ans << endl;
}
return 0;
}
二. 专题:图论基础
(1)最短路:dijkstra
1)无优化版本:
#include<bits/stdc++.h>
#define LL long long
using namespace std;
struct node
{
int v, w;
};
int n, m, s, d[200005], vis[200005]; // 点数 边数 起始点
vector<node> G[200005];
void dijkstra(int s) // 初始时所有点都在一个大集合里
{
for (int i = 0; i <= n; i ++) // 多设置一个不存在的点0,后续用于比较
d[i] = 1e9; // 设置初始距离全为无穷大
d[s] = 0; // 源点距离为零
for (int i = i; i < n; i ++) // 更新所有点的总次数为n - 1(n也可以)
{
int u = 0;
for (int j = 1; j <= n; j ++) // 枚举所有点
{
if (!vis[j] && d[j] < d[u]) // 找到一个还在集合中并且到原点距离最近的点
u = j;
vis[u] = 1; // 该点出集合
for (auto ed : G[u]) // 松弛操作,更新该点所有邻点到原点的最短距离
{
int v = ed.v, w = ed.w;
d[v] = min(d[v], d[u] + w);
}
}
}
}
int main()
{
cin >> n >> m >> s;
for (int i = 1; i <= m; i ++)
{
int u, v, w;
cin >> u >> v >> w;
G[u].push_back({v, w});
}
dijkstra(s);
return 0;
}
2)优先队列优化
在枚举所有点这个循环中,出现了很多无效操作,已经出集合的点和已经找到最近点但还会继续找下去,因此用大根堆(距离取反)来减少避免循环查找。
#include<bits/stdc++.h>
#define LL long long
using namespace std;
int n, m, s, d[200005], vis[200005];
priority_queue<pair<int, int> > pq;
void dijkstra(int s)
{
for (int i = 0;i <= n; i ++)
d[i] = 1e9;
d[s] = 0;
pq.push({0, s});
while (pq.size())
{
auto t = pq.top();
pq.pop();
int u = t.second;
if (vis[u]) continue;
vis[u] = 1;
for (auto ed : G[u])
{
int v = ed.v, w = ed.w;
if (d[v] > d[u] + w)
{
d[v] = d[u] + w;
pq.push({-d[v], v});
}
}
}
}
int main()
{
cin >> n >> m >> s;
for (int i = 1; i <= m; i ++)
{
int u, v, w;
cin >> u >> v >> w;
G[u].push_back({v,w})
}
dijkstra(s);
return 0;
}