1、分蛋糕
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1010;
int n, k, a[N];
int main() {
cin >> n >> k;
for (int i = 0; i < n; i ++ ) cin >> a[i];
int res = 0;
for (int i = 0; i < n; i ++ ) {
int j = i, s = 0;
while (j < n && s < k) s += a[j ++ ];
res ++ ;
i = j - 1;
}
cout << res << endl;
return 0;
}
2、学生排队
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1010;
int n, m, a[N];
void move(int pos, int dist, int t) {
while (dist--) {
swap(a[pos], a[pos + t]);
pos += t;
}
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) a[i] = i;
while (m--) {
int p, q, pos; cin >> p >> q;
for (int i = 1; i <= n; i++)
if (a[i] == p) pos = i;
if (q > 0) move(pos, q, 1);
else move(pos, -q, -1);
}
for (int i = 1; i <= n; i++) cout << a[i] << " ";
puts("");
return 0;
}
3、Markdown
重点:
- 处理嵌套
- 注意区块!
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
vector<string> strs;
inline int work_link(string str, int i) {
string text, link;
for (i++; str[i] != ']'; i++) {
char c = str[i];
if (c == '_') {
text += "<em>";
i++;
while (str[i] != '_') text += str[i++];
text += "</em>";
} else text += c;
}
for (i += 2; str[i] != ')'; i++) link += str[i];
printf("<a href=\"%s\">%s</a>", link.c_str(), text.c_str());
return i;
}
inline int work_em(string str, int i) {
printf("<em>");
for (i++; str[i] != '_'; i++) {
char c = str[i];
if (c == '[') i = work_link(str, i); // 处理嵌套
else cout << c;
}
printf("</em>");
return i;
}
inline void work_line(string str) {
int k = 0;
while (str[k] == ' ') k++;
str = str.substr(k);
for (int i = 0; i < str.size(); i++) {
char c = str[i];
if (c == '_') i = work_em(str, i);
else if (c == '[') i = work_link(str, i);
else cout << c;
}
}
inline void work(int a, int b) {
if (strs[a][0] == '#') {
int k = 0;
while (strs[a][k] == '#') k++;
printf("<h%d>", k);
work_line(strs[a].substr(k));
printf("</h%d>\n", k);
} else if (strs[a][0] == '*') {
printf("<ul>\n");
for (int i = a; i <= b; i++) {
printf("<li>");
work_line(strs[i].substr(1));
printf("</li>\n");
}
printf("</ul>\n");
} else {
printf("<p>");
for (int i = a; i <= b; i++) {
work_line(strs[i]);
if (i != b) cout << endl;
}
printf("</p>\n");
}
}
int main() {
string str;
while (getline(cin, str)) strs.push_back(str);
for (int i = 0; i < strs.size(); i++) {
if (strs[i].empty()) continue;
int j = i + 1;
while (j < strs.size() && strs[j].size()) j++; // 找出一个区块
work(i, j - 1);
i = j - 1;
}
return 0;
}
4、地铁修建
从点 1 1 1 到点 n n n 有 m m m 条边可以选择,现在要求做多选择 n n n 条边,使得从 1 1 1 到 n n n 连通且边上的最大权值最小。
注意审题,因为每家公司的施工时间一样,所以如果选择的 k k k 条线路同时施工,那么整条线路的施工时间就取决于施工时间最长的一条线路。
如果每一次都只选择边权小于等于 m i d mid mid 的边,那么这个图中所有边权小于等于 m i d mid mid 的边的边权可以看做 1 1 1,大于 m i d mid mid 的边的边权看做 0 0 0,因此可以使用 b f s bfs bfs 即可。
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 1e5 + 10, M = 4e5 + 10;
int n, m;
int h[N], e[M], w[M], ne[M], idx;
int dist[N];
int q[N];
inline void add(int a, int b, int c) {
w[idx] = c, e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
inline int bfs(int mid) {
memset(dist, 0x3f, sizeof dist); dist[1] = 0;
int hh = 0, tt = 0; q[0] = 1;
while (hh <= tt) {
int t = q[hh++];
for (int i = h[t]; ~i; i = ne[i]) {
if (w[i] > mid) continue;
int j = e[i];
if (dist[j] > dist[t] + 1) {
dist[j] = dist[t] + 1;
q[++tt] = j;
}
}
}
return dist[n];
}
int main() {
scanf("%d%d", &n, &m);
memset(h, -1, sizeof h);
while (m--) {
int a, b, c; scanf("%d%d%d", &a, &b, &c);
add(a, b, c), add(b, a, c);
}
int l = 0, r = 1e6;
while (l < r) {
int mid = (l + r) >> 1;
if (bfs(mid) <= n) r = mid;
else l = mid + 1;
}
printf("%d\n", r);
return 0;
}