PTA 天梯赛题目整理
并查集板子
(1)朴素并查集:
int p[N]; //存储每个点的祖宗节点
// 返回x的祖宗节点
int find(int x)
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
// 初始化,假定节点编号是1~n
for (int i = 1; i <= n; i ++ ) p[i] = i;
// 合并a和b所在的两个集合:
p[find(a)] = find(b);
(2)维护size的并查集:
int p[N], size[N];
//p[]存储每个点的祖宗节点, size[]只有祖宗节点的有意义,表示祖宗节点所在集合中的点的数量
// 返回x的祖宗节点
int find(int x)
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
// 初始化,假定节点编号是1~n
for (int i = 1; i <= n; i ++ )
{
p[i] = i;
size[i] = 1;
}
// 合并a和b所在的两个集合:
size[find(b)] += size[find(a)];
p[find(a)] = find(b);
(3)维护到祖宗节点距离的并查集:
int p[N], d[N];
//p[]存储每个点的祖宗节点, d[x]存储x到p[x]的距离
// 返回x的祖宗节点
int find(int x)
{
if (p[x] != x)
{
int u = find(p[x]);
d[x] += d[p[x]];
p[x] = u;
}
return p[x];
}
// 初始化,假定节点编号是1~n
for (int i = 1; i <= n; i ++ )
{
p[i] = i;
d[i] = 0;
}
// 合并a和b所在的两个集合:
p[find(a)] = find(b);
d[find(a)] = distance; // 根据具体问题,初始化find(a)的偏移量
L2
难点
18(多项式) 28/34(大模拟)
L2-001 紧急救援
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std ;
const int N = 510 ;
int n, m, s, d, dist[N], g[N][N], num[N], r[N], rescure[N], pre[N] ;
// num表示到当前结点的路径数量
// r表示到当前结点的救援队数量 rescue表示当前结点的救援队数量
// pre表示走到当前结点的上一个结点
bool st[N] ;
void print_path(int i) // 递归打印
{
if (i == s)
{
printf("%d", i) ;
return ;
}
print_path(pre[i]) ;
printf(" %d", i) ;
}
void dijkstra()
{
memset(dist, 0x3f, sizeof dist) ;
dist[s] = 0 ;
num[s] = 1 ;
r[s] = rescure[s] ;
for (int i = 0;i < n;i ++ )
{
int t = -1 ;
for (int j = 0;j < n;j ++ )
{
if (!st[j] && (t == -1 || dist[t] > dist[j]))
{
t = j ;
}
}
st[t] = true ;
for (int j = 0;j < n;j ++ )
{
if (dist[j] > dist[t] + g[t][j])
{
dist[j] = dist[t] + g[t][j] ;
num[j] = num[t] ;
r[j] = r[t] + rescure[j] ;
pre[j] = t ;
}
else if (dist[j] == dist[t] + g[t][j])
{
num[j] = num[t] + num[j] ;
if (r[j] < r[t] + rescure[j])
{
r[j] = r[t] + rescure[j] ;
pre[j] = t ;
}
}
}
}
}
int main()
{
cin >> n >> m >> s >> d ;
for (int i = 0;i < n;i ++ ) cin >> rescure[i] ;
memset(g, 0x3f, sizeof g) ;
for (int i = 0;i < m;i ++ )
{
int a, b, c; cin >> a >> b >> c;
g[a][b] = g[b][a] = c;
}
dijkstra() ;
printf("%d %d\n", num[d], r[d]);
print_path(d) ;
return 0 ;
}
L2-002 链表去重
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int N = 100010;
bool st[N];
struct node {
int addr, key, next, idx;
}nodes[N];
bool cmp(node a, node b) {
return a.idx < b.idx;
}
int main()
{
int h, n, x;
int cnt1 = 0, cnt2 = 0;
scanf("%d%d", &h, &n);
for (int i = 0; i < N; i ++ ) nodes[i].idx = 2 * N;
for (int i = 0; i < n; i ++ )
{
scanf("%d", &x);
nodes[x].addr = x;
scanf("%d%d", &nodes[x].key, &nodes[x].next);
}
for (int i = h; i != -1; i = nodes[i].next)
{
if (!st[abs(nodes[i].key)])
{
st[abs(nodes[i].key)] = true;
nodes[i].idx = cnt1 ++ ;
}
else
{
nodes[i].idx = N + cnt2;
cnt2 ++ ;
}
}
sort(nodes, nodes + N, cmp);
int cnt = cnt1 + cnt2;
for (int i = 0; i < cnt; i ++ )
{
if (i != cnt1 - 1 && i != cnt - 1)
{
printf("%05d %d %05d\n", nodes[i].addr, nodes[i].key, nodes[i+1].addr);
}
else
{
printf("%05d %d -1\n", nodes[i].addr, nodes[i].key);
}
}
return 0;
}
L2-003 月饼
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 1010;
struct node
{
double num, price, weight;
}nodes[N];
bool cmp(node a, node b)
{
return a.weight > b.weight;
}
int main()
{
int n, need;
cin >> n >> need;
for (int i = 0; i < n; i ++ ) cin >> nodes[i].num;
for (int i = 0; i < n; i ++ ) cin >> nodes[i].price;
for (int i = 0; i < n; i ++ ) nodes[i].weight = nodes[i].price / nodes[i].num;
sort(nodes, nodes + n, cmp);
double res = 0;
for (int i = 0; i < n; i ++ )
{
if (nodes[i].num <= need)
{
res += nodes[i].price;
}
else
{
res += nodes[i].weight * need;
break;
}
need -= nodes[i].num;
}
printf("%.2lf\n", res);
return 0;
}
L2-004 这是二叉搜索树吗
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
bool isMirror;
int pre[N], post[N], idx;
// get BST's sequence of post-order
void getpost(int root, int tail)
{
if (root > tail) return;
int i = root + 1, j = tail;
if (!isMirror)
{
// 找到右子树的根节点
while (i <= tail && pre[root] > pre[i]) i ++ ;
// 找到左子树的最后一个结点
while (j > root && pre[root] <= pre[j]) j -- ;
}
else
{
// 镜像
// 找到右子树的根节点
while (i <= tail && pre[root] <= pre[i]) i ++ ;
// 找到左子树的最后一个结点
while (j > root && pre[root] > pre[j]) j -- ;
}
// 判断是否到了根节点, 不判断也可以
// if (i - j != 1) return;
// 递归左子树
getpost(root + 1, j);
// 递归右子树
getpost(i, tail);
// 后序遍历结点
post[idx ++ ] = pre[root];
}
int main()
{
int n; cin >> n;
for (int i = 0; i < n; i ++ ) cin >> pre[i];
getpost(0, n - 1);
if (idx != n)
{
isMirror = true;
idx = 0;
getpost(0, n - 1);
}
if (idx == n)
{
// 注意输入格式, 不能有多余空格
cout << "YES" << endl << post[0];
for (int i = 1; i < idx; i ++ ) cout << " " << post[i];
}
else
{
cout << "NO" << endl;
}
return 0;
}
L2-005 集合相似度
#include <iostream>
#include <cstdio>
#include <set>
using namespace std;
const int N = 100;
set<int> s[N];
int main()
{
int n, m, k, x, a, b;
cin >> n;
for (int i = 0; i < n; i ++ )
{
cin >> m;
for (int j = 0; j < m; j ++ )
{
cin >> x;
s[i].insert(x);
}
}
cin >> k;
for (int i = 0; i < k; i ++ )
{
cin >> a >> b;
int nc = 0, nt = s[b - 1].size();
for (auto it = s[a - 1].begin(); it != s[a - 1].end(); it ++ )
{
if (s[b - 1].find(*it) == s[b - 1].end())
nt ++ ;
else
nc ++ ;
}
double ans = (double)nc / nt * 100;
printf("%.2lf%%\n", ans);
}
return 0;
}
L2-006 树的遍历
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
const int N = 50;
int n, post[N], in[N];
map<int, int> level;
void pre(int rt, int st, int ed, int idx)
{
if (st > ed) return;
int i = st;
while (i < ed && in[i] != post[rt]) i ++ ; // 找到当前子树根节点在中序遍历中的位置
// 先序遍历处理代码
level[idx] = post[rt];
pre(rt - 1 - ed + i, st, i - 1, 2 * idx + 1); // idx为子树的根结点在层序遍历中的位置
pre(rt - 1, i + 1, ed, 2 * idx + 2);
}
int main()
{
cin >> n;
for (int i = 0; i < n; i ++ ) cin >> post[i];
for (int i = 0; i < n; i ++ ) cin >> in[i];
pre(n-1, 0, n-1, 0);
auto it = level.begin();
printf("%d", it->second);
while (++it != level.end()) printf(" %d", it->second);
return 0;
}
L2-007 家庭房产
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
struct DATA{
int id, fid, mid, num, area;
int cid[10];
} datas[N];
struct node{
int id, people;
double num, area;
bool flag = false;
}ans[N * 10];
int p[N*10];
bool vis[N*10];
int find(int x)
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
void Union(int a, int b)
{
a = find(a);
b = find(b);
if (a > b) swap(a, b);
p[b] = p[a];
}
int cmp(node a, node b)
{
if (a.area != b.area)
return a.area > b.area;
else
return a.id < b.id;
}
int main()
{
int n, k, cnt = 0;
cin >> n;
for (int i = 0; i < N * 10; i ++ ) p[i] = i;
for (int i = 0; i < n; i ++ )
{
cin >> datas[i].id >> datas[i].fid >> datas[i].mid >> k;
vis[datas[i].id] = true;
if (datas[i].fid != -1) {
vis[datas[i].fid] = true;
Union(datas[i].id, datas[i].fid);
}
if (datas[i].mid != -1) {
vis[datas[i].mid] = true;
Union(datas[i].id, datas[i].mid);
}
for (int j = 0; j < k; j ++ )
{
cin >> datas[i].cid[j];
vis[datas[i].cid[j]] = true;
Union(datas[i].cid[j], datas[i].id);
}
cin >> datas[i].num >> datas[i].area;
}
for (int i = 0; i < n; i ++ )
{
int id = find(datas[i].id);
ans[id].id = id;
ans[id].num += datas[i].num;
ans[id].area += datas[i].area;
ans[id].flag = true;
}
for (int i = 0; i < N * 10; i ++ )
{
if (vis[i])
ans[find(i)].people ++ ;
if (ans[i].flag)
cnt ++ ;
}
for (int i = 0; i < N * 10; i ++ )
{
if (ans[i].flag)
{
ans[i].num = (double)(ans[i].num * 1.0 / ans[i].people);
ans[i].area = (double)(ans[i].area * 1.0 / ans[i].people);
}
}
sort(ans, ans + N * 10, cmp);
cout << cnt << endl;
for (int i = 0; i < cnt; i ++ )
printf("%04d %d %.3lf %.3lf\n", ans[i].id, ans[i].people, ans[i].num, ans[i].area);
return 0;
}
L2-008 最长对称子串
#include <iostream>
#include <cstring>
#include <algorithm>
#include <string>
using namespace std;
const int N = 1010;
int main()
{
string s;
getline(cin, s);
int res = -1, temp = 0;
for (int i = 0; i < s.size(); i ++ )
{
// 奇数情况
temp = 1;
for (int j = 1; j < s.size(); j ++ )
{
if (i - j < 0 || i + j >= s.size() || s[i - j] != s[i + j]) break;
temp += 2;
}
res = max(res, temp);
// 偶数情况
temp = 0;
for (int j = 1; j < s.size(); j ++ )
{
if (i - j + 1 < 0 || i + j >= s.size() || s[i - j + 1] != s[i + j]) break;
temp += 2;
}
res = max(res, temp);
}
cout << res << endl;
return 0;
}
L2-009 抢红包
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 10010;
struct node {
int id, tot, num;
}nodes[N];
bool cmp(node a, node b)
{
if (a.tot != b.tot)
return a.tot > b.tot;
else if (a.num != b.num)
return a.num > b.num;
else
return a.id < b.id;
}
int main()
{
int n, k, id, val;
cin >> n;
for (int i = 1; i <= n; i ++ )
{
cin >> k;
nodes[i].id = i;
for (int j = 0; j < k; j ++ )
{
cin >> id >> val;
nodes[id].tot += val;
nodes[i].tot -= val;
nodes[id].num ++ ;
}
}
sort(nodes + 1, nodes + n + 1, cmp);
for (int i = 1; i <= n; i ++ )
{
double t = (double)(nodes[i].tot * 1.00 / 100);
printf("%d %.2lf\n", nodes[i].id, t);
}
return 0;
}
L2-010 排座位
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 110;
int p[N], rival[N][N];
int find(int x)
{
if (x != p[x]) p[x] = find(p[x]);
return p[x];
}
void _union(int a, int b)
{
a = find(a);
b = find(b);
p[a] = p[b];
}
int main()
{
int n, m, k, a, b, c;
cin >> n >> m >> k;
for (int i = 1; i <= n; i ++ ) p[i] = i;
for (int i = 0; i < m; i ++ )
{
cin >> a >> b >> c;
if (c == 1) _union(a, b);
else {
rival[a][b] = 1;
rival[b][a] = 1;
}
}
for (int i = 0; i < k; i ++ )
{
cin >> a >> b;
if (find(a) == find(b) && rival[a][b] == 0)
puts("No problem");
else if (find(a) == find(b) && rival[a][b] == 1)
puts("OK but...");
else if (find(a) != find(b) && rival[a][b] == 0)
puts("OK");
else if (find(a) != find(b) && rival[a][b] == 1)
puts("No way");
}
return 0;
}
L2-011 玩转二叉树
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
const int N = 50;
int pre[N], in[N];
map<int, int> lev;
void level(int rt, int st, int ed, int idx)
{
if (st > ed) return;
int i = st;
while (i < ed && in[i] != pre[rt]) i ++ ; // 确定当前子树的根节点
lev[idx] = pre[rt];
level(rt + 1, st, i - 1, idx * 2 + 2);
level(rt + i - st + 1, i + 1, ed, idx * 2 + 1);
}
int main()
{
int n; cin >> n;
for (int i = 0; i < n; i ++ ) cin >> in[i];
for (int i = 0; i < n; i ++ ) cin >> pre[i];
level(0, 0, n-1, 0);
auto it = lev.begin();
cout << it->second;
while (++it != lev.end())
{
printf(" %d", it->second);
}
return 0;
}
L2-012 关于堆的判断
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
const int N = 1010;
int n, m, h[N];
map<int, int> mp;
void up(int x)
{
while (x/2 && h[x/2] > h[x])
{
swap(h[x/2], h[x]);
x >>= 1;
}
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i ++ )
{
cin >> h[i];
up(i);
}
for (int i = 1; i <= n; i ++ ) mp[h[i]] = i;
string s;
int x, y;
for (int i = 0; i < m; i ++ )
{
cin >> x >> s;
if (s[0] == 'a')
{
cin >> y;
getline(cin, s);
if (mp[x]/2 == mp[y]/2) cout << 'T' << endl;
else cout << 'F' << endl;
} else {
cin >> s;
cin >> s;
if (s[0] == 'r') {
if (mp[x] == 1) cout << 'T' << endl;
else cout << 'F' << endl;
} else if (s[0] == 'p') {
cin >> s;
cin >> y;
if (mp[y]/2 == mp[x]) cout << 'T' << endl;
else cout << 'F' << endl;
} else {
cin >> s;
cin >> y;
if (mp[x]/2 == mp[y]) cout << 'T' << endl;
else cout << 'F' << endl;
}
}
}
return 0;
}
L2-013 红色警报
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 510;
bool st[N];
int g[N][N], n, m, k;
void dfs(int x)
{
st[x] = true;
for (int i = 0; i < n; i ++ )
if (!st[i] && g[x][i] == 1)
dfs(i);
}
int calc_cnt()
{
int cnt = 0;
memset(st, false, sizeof st);
for (int i = 0; i < n; i ++ )
if (!st[i])
{
dfs(i);
cnt ++ ;
}
return cnt;
}
int main()
{
cin >> n >> m;
int a, b, c;
for (int i = 0; i < m; i ++ )
{
cin >> a >> b;
g[a][b] = g[b][a] = 1;
}
int cnt = calc_cnt();
cin >> k;
for (int i = 0; i < k; i ++ )
{
cin >> c;
for (int j = 0; j < n; j ++ )
{
g[c][j] = g[j][c] = 0;
}
int t_cnt = calc_cnt();
if (t_cnt > cnt + 1)
printf("Red Alert: City %d is lost!\n", c);
else
printf("City %d is lost.\n", c);
cnt = t_cnt;
if (i == n - 1)
printf("Game Over.\n");
}
return 0;
}
L2-014 列车调度
#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>
using namespace std;
const int N = 10010;
set<int> s;
int n, t;
int main()
{
cin >> n;
s.insert(0);
// set自动排序
for (int i = 0; i < n; i ++ )
{
cin >> t;
if (t < *s.rbegin()) // end指向最后一个元素的后一个, rbegin指向最后一个元素
{
s.erase(*(s.upper_bound(t)));
}
s.insert(t);
}
cout << s.size() - 1 << endl;
return 0;
}
L2-015 互评成绩
#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>
using namespace std;
const int N = 10010;
double stu[N], grade[20];
int main()
{
int n, k, m; cin >> n >> k >> m;
for (int i = 0; i < n; i ++ )
{
double mmax = -1, mmin = 110, sum = 0;
for (int j = 0; j < k; j ++ )
{
cin >> grade[j];
sum += grade[j];
mmax = max(mmax, grade[j]);
mmin = min(mmin, grade[j]);
}
stu[i] = (sum - mmax - mmin) / (k - 2);
}
sort(stu, stu + n);
for (int i = n - m; i < n; i ++ )
{
if (i == n - 1) printf("%.3lf\n", stu[i]);
else printf("%.3lf ", stu[i]);
}
return 0;
}
L2-016 愿天下有情人都是失散多年的兄妹
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 100010;
int n, k;
char gender[N];
bool st[N], flag;
vector<int> g[N];
void dfs(int u, int d)
{
if (d == 5) return;
if (st[u])
{
flag = true;
return;
}
st[u] = true;
for (int i = 0; i < g[u].size(); i ++ )
dfs(g[u][i], d + 1);
}
int main()
{
int x, f, m;
cin >> n;
for (int i = 0; i < n; i ++ )
{
cin >> x;
cin >> gender[x] >> f >> m;
if (f != -1) gender[f] = 'M', g[x].push_back(f);
if (m != -1) gender[m] = 'F', g[x].push_back(m);
}
cin >> k;
int a, b;
for (int i = 0; i < k; i ++ )
{
cin >> a >> b;
if (gender[a] == gender[b])
{
cout << "Never Mind" << endl;
continue;
}
memset(st, false, sizeof st);
flag = false;
dfs(a, 0);
dfs(b, 0);
if (flag)
cout << "No" << endl;
else
cout << "Yes" << endl;
}
return 0;
}
L2-017 人以群分
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100010;
LL p[N];
int main()
{
int n; cin >> n;
for (int i = 0; i < n; i ++ ) cin >> p[i];
sort(p, p + n);
LL res = 0;
for (int i = 0; i < n; i ++ )
{
if (i <= n / 2 - 1) res -= p[i];
else res += p[i];
}
cout << "Outgoing #: " << n / 2 + (n & 1) << endl ;
cout << "Introverted #: " << n / 2 << endl ;
cout << "Diff = " << res << endl ;
return 0;
}
L2-018 多项式A除以B
L2-019 悄悄关注
#include <iostream>
#include <cstring>
#include <algorithm>
#include <string>
#include <map>
using namespace std;
const int N = 10010;
map<string, bool> st;
map<string, int> mp;
int main()
{
int n, m, cnt, avg = 0;
string s;
cin >> n;
for (int i = 0; i < n; i ++ )
{
cin >> s;
st[s] = true;
}
cin >> m;
for (int i = 0; i < m; i ++ )
{
cin >> s >> cnt;
mp[s] = cnt;
avg += cnt;
}
avg /= m;
bool flag = false;
for (auto it : mp)
{
if (it.second > avg && !st[it.first])
{
cout << it.first << endl;
flag = true;
}
}
if (!flag) cout << "Bing Mei You" << endl;
return 0;
}
L2-020 功夫传人
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 100010;
vector<vector<int> > v;
int n, k;
double z, r, res = 0;
bool st[N];
void dfs(int idx, double p)
{
if (st[idx])
{
res += p * v[idx][0];
return;
}
for (int i = 0; i < v[idx].size(); i ++ )
dfs(v[idx][i], p * (1 - r / 100));
}
int main()
{
cin >> n >> z >> r;
v.resize(n);
int t;
for (int i = 0; i < n; i ++ )
{
cin >> k;
if (k == 0)
{
cin >> t;
v[i].push_back(t);
st[i] = true;
}
for (int j = 0; j < k; j ++ )
{
cin >> t;
v[i].push_back(t);
}
}
dfs(0, z);
cout << (int)res << endl;
return 0;
}
L2-021 点赞狂魔
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 1e7 + 10;
bool st[N];
struct usr {
string name;
int sum, cnt;
};
bool cmp(usr a, usr b)
{
if (a.cnt != b.cnt) return a.cnt > b.cnt;
return 1.0 * a.sum / a.cnt < 1.0 * b.sum / b.cnt;
}
int main()
{
int n; cin >> n;
vector<usr> v(n);
for (int i = 0; i < n; i ++ )
{
memset(st, false, sizeof st);
int k, t, cnt = 0;
string name;
cin >> name >> k;
for (int j = 0; j < k; j ++ )
{
cin >> t;
if (!st[t])
{
st[t] = true;
cnt ++ ;
}
}
v[i] = {name, k, cnt};
}
int minv = min(n, 3);
partial_sort(v.begin(), v.begin() + minv, v.end(), cmp);
for (int i = 0; i < minv; i ++ )
{
if (i != 0) cout << " ";
cout << v[i].name;
}
for (int i = 0; i < 3 - minv; i ++ )
cout << " -";
cout << endl;
return 0;
}
L2-022 重排链表
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 100010;
struct node {
int id, data, next;
}nodes[N];
int main()
{
int h, n;
cin >> h >> n;
vector<node> v, ans;
for (int i = 0; i < n; i ++ )
{
int tid, tdata, tnext;
cin >> tid >> tdata >> tnext;
nodes[tid] = {tid, tdata, tnext};
}
while (h != -1)
{
v.push_back(nodes[h]);
h = nodes[h].next;
}
int l = 0, r = v.size() - 1;
while (1)
{
ans.push_back(v[r]);
r -- ;
if (r - l == -1) break;
ans.push_back(v[l]);
l ++ ;
if (r - l == -1) break;
}
for (int i = 0; i < ans.size(); i ++ )
{
if (i != ans.size() - 1)
printf("%05d %d %05d\n", ans[i].id, ans[i].data, ans[i+1].id);
else
printf("%05d %d -1\n", ans[i].id, ans[i].data);
}
return 0;
}
L2-023 图着色问题
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <set>
using namespace std ;
const int N = 510 ; int n, m, k ;
vector<vector<int>> v(N) ; // 用 vector 作邻接表来存边
int color[N] ; // 记录 每个点的 color
bool check(int i) // 检查每个点的 color 是否与其邻边不一样
{
for (int j = 0;j < v[i].size();j ++ )
{
if (color[i] == color[v[i][j]]) return false ;
}
return true ;
}
int main()
{
cin >> n >> m >> k ;
for (int i = 0;i < m;i ++ )
{
int a, b; cin >> a >> b;
v[a].push_back(b) ;
v[b].push_back(a) ;
}
int t ; cin >> t ;
while (t -- )
{
bool flag = true ; set<int> s ; // set 存储当前图的颜色种数 去重
for (int i = 1;i <= n;i ++ )
{
cin >> color[i] ;
s.insert(color[i]) ;
}
if (s.size() != k)
{
cout << "No" << endl ;
flag = false ;
}
else
{
for (int i = 1;i <= n;i ++ )
{
if (!check(i))
{
cout << "No" << endl ;
flag = false ;
break ;
}
}
}
if (flag) cout << "Yes" << endl ;
}
return 0 ;
}
L2-024 部落
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 10010;
int p[N];
int find(int x)
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
int main()
{
int n, k, t, x; cin >> n;
int mmax = -1;
for (int i = 1; i <= N - 10; i ++ ) p[i] = i;
for (int i = 0; i < n; i ++ )
{
cin >> k;
cin >> t;
mmax = max(mmax, t);
for (int j = 1; j <= k - 1; j ++ )
{
cin >> x;
mmax = max(mmax, x);
int a = find(x), b = find(t);
if (a != b) p[a] = p[b];
}
}
int cnt = 0;
for (int i = 1; i <= mmax; i ++ )
if (i == find(i)) cnt ++ ;
cout << mmax << " " << cnt << endl;
int q; cin >> q;
while (q -- )
{
int a, b; cin >> a >> b;
if (find(a) != find(b)) cout << "N" << endl;
else cout << "Y" << endl;
}
return 0;
}
L2-025 分而治之
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 10010;
int n, m, k, aa[N], a[N];
void check()
{
for (int i = 1; i <= n; i ++ )
{
if (a[i] > 0)
{
cout << "NO" << endl;
return;
}
}
cout << "YES" << endl;
return;
}
int main()
{
cin >> n >> m;
vector<vector<int> > v(n + 1);
while (m -- )
{
int c1, c2;
cin >> c1 >> c2;
aa[c1] ++ ;
aa[c2] ++ ;
v[c1].push_back(c2);
v[c2].push_back(c1);
}
cin >> k;
while (k -- )
{
int cnt, num;
cin >> cnt;
for (int i = 1; i <= n; i ++ ) a[i] = aa[i];
for (int i = 0; i < cnt; i ++ )
{
cin >> num;
a[num] = 0;
for (int j = 0; j < v[num].size(); j ++ )
a[v[num][j]] -- ;
}
check();
}
return 0;
}
L2-026 小字辈
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
const int N = 100010;
vector<int>v[N];
int n ,a[N] ,depth[N] ,flag;
int bfs() {
queue<int>q;
q.push(v[0][0]);//根节点只有一个孩子,直接把这个孩子传入队列
int x;
while (!q.empty()) {
x = q.front();
q.pop();
for (int i = 0; i < v[x].size(); i++) {//搜索所有的孩子
depth[v[x][i]] = depth[x] + 1;//深度为父节点+1
q.push(v[x][i]);
}
}
return depth[x];//返回树的深度
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
if (a[i] == -1) {//将根节点改为0
a[i] = 0;
depth[i] = 1;//根节点的深度为1
}
v[a[i]].push_back(i);//i是a[i]的孩子
}
int ans = bfs();
cout << ans << endl;
// 按顺序遍历
for (int i = 1; i <= n; i++) {//遍历找出距离根节点最远的叶节点
if (depth[i] == ans) {
if(flag) cout << ' ';
cout << i ,flag = 1;
}
}
cout << endl;
return 0;
}
L2-027 名人堂与代金券
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 10010;
struct stu {
string name;
int score;
};
int rk[N];
bool cmp(stu a, stu b)
{
if (a.score != b.score) return a.score > b.score;
return a.name < b.name;
}
int main()
{
int n, g, k, sum = 0;
cin >> n >> g >> k;
vector<stu> v(n);
for (int i = 0; i < n; i ++ )
{
cin >> v[i].name >> v[i].score;
if (v[i].score >= 60) sum += 20;
if (v[i].score >= g) sum += 30;
}
sort(v.begin(), v.end(), cmp);
rk[0] = 1;
for (int i = 1; i < n; i ++ )
{
if (v[i].score == v[i-1].score)
rk[i] = rk[i-1];
else
rk[i] = i + 1;
}
cout << sum << endl;
for (int i = 0; rk[i] <= k && i < n; i ++ )
cout << rk[i] << " " << v[i].name << " " << v[i].score << endl;
return 0;
}
L2-028 秀恩爱分得快
#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
bool cmp (int a, int b) {
if(abs(a) == 1000) return true;
if(abs(b) == 1000) return false;
return abs(a) < abs(b);
}
int main(){
int n, m, num, k, sex[1010] = {0}, love[3] ;
double sum[1010] = {0}, maxn[3] = {0} ;
string s ;
cin >> n >> m ;
vector<vector<int>> v(m), ans(3);
for(int i = 0; i < m; i++) {
cin >> k;
for(int j = 0; j < k; j++){
cin >> s;
if(s == "0") s = "1000";
if(s == "-0") s = "-1000";
num = stoi(s); // 字符串转换函数
sex[abs(num)] = num;
v[i].push_back(num);
}
}
for(int i = 1; i <= 2; i++) {
cin >> s;
if(s == "0") s = "1000";
if(s == "-0") s = "-1000";
love[i] = stoi(s);
}
for(int k = 1; k <= 2; k++) {
for(int i = 0; i < m; i++) {
int flag = 0;
for(int j = 0; j < v[i].size(); j++){
if(v[i][j] == love[k]) {
flag = 1;
break;
}
}
if(flag == 1) {
for(int j = 0; j < v[i].size(); j++){
if(love[k] * v[i][j] < 0) {
sum[(int)abs(v[i][j])] += 1.0 / v[i].size();
}
}
}
}
}
maxn[1] = maxn[2] = -1;
for(int k = 1; k <= 2; k++) {
for(int i = 1; i <= 1000; i++) {
if(love[k] * sex[i] < 0) {
if(sum[i] > maxn[k]) {
maxn[k] = sum[i];
ans[k].clear();
ans[k].push_back(sex[i]);
}else if(sum[i] == maxn[k]) {
ans[k].push_back(sex[i]);
}
}
}
}
if(maxn[1] == sum[(int)abs(love[2])] && maxn[2] == sum[(int)abs(love[1])]) {
string s1 = to_string(love[1]), s2 = to_string(love[2]);
if(love[1] == 1000) s1 = "0";
if(love[1] == -1000) s1 = "-0";
if(love[2] == 1000) s2 = "0";
if(love[2] == -1000) s2 = "-0";
cout << s1 << " " << s2 << endl;
return 0;
}
for(int k = 1; k <= 2; k++) {
sort(ans[k].begin(), ans[k].end(), cmp);
for(int i = 0; i < ans[k].size(); i++) {
string s1 = to_string(love[k]), s2 = to_string(ans[k][i]);
if(love[k] == 1000) s1 = "0";
if(love[k] == -1000) s1 = "-0";
if(ans[k][i] == 1000) s2 = "0";
if(ans[k][i] == -1000) s2 = "-0";
cout << s1 << " " << s2 << endl;
}
}
return 0;
}
L2-029 特立独行的幸福
#include <bits/stdc++.h>
using namespace std;
int A, B, flag, num[10001], notIndep[10001];
bool isPrime(int a) {
if (a == 1) return false;
for (int i = 2; i <= sqrt(a); i++)
if (a % i == 0) return false;
return true;
}
bool isIndep(int x) {
set<int> mark;
int X = x, temp1, temp2;
while (X != 1) {
mark.insert(X);
temp1 = 0;
while (X) {
temp2 = X % 10;
X /= 10;
temp1 += temp2 * temp2;
}
num[x]++;
notIndep[temp1] = 1;
X = temp1;
if (mark.count(X)) return false;
}
return true;
}
int main() {
cin >> A >> B;
vector<int> ans;
for (int i = A; i <= B; i++)
if (isIndep(i)) ans.push_back(i);
for (int i = 0; i < ans.size(); i++) {
if (isPrime(ans[i])) num[ans[i]] <<= 1;
if (!notIndep[ans[i]]) {
cout << ans[i] << ' ' << num[ans[i]] << endl;
flag = 1;
}
}
if (!flag) cout << "SAD";
return 0;
}
L2-030 冰岛人
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
typedef pair<int, string> PIS;
const int N = 100010;
map<string, PIS> record; // 映射关系: 孩子的名 -> 父亲的名
string check(string s1, string s2)
{
int cnt1 = 0, cnt2 = 0;
while (s1 != "")
{
cnt2 = 0;
string s3 = s2;
while (s3 != "")
{
if (s3 == s1 && (cnt1 < 4 || cnt2 < 4)) return "No";
if (cnt1 >= 4 && cnt2 >= 4) return "Yes";
s3 = record[s3].second;
cnt2 ++ ;
}
s1 = record[s1].second;
cnt1 ++ ;
}
return "Yes";
}
int main()
{
int n, m; cin >> n;
string fName, lName;
for (int i = 0; i < n; i ++ )
{
cin >> fName >> lName;
if (lName.back() == 'n') record[fName] = {1, lName.substr(0, lName.length()-4) };
else if (lName.back() == 'r') record[fName] = {0, lName.substr(0, lName.length()-7) };
else if (lName.back() == 'm') record[fName].first = 1;
else record[fName].first = 0;
}
cin >> m;
string fName1, fName2, tmp;
for (int i = 0; i < m; i ++ )
{
cin >> fName1 >> tmp >> fName2 >> tmp;
if (!record.count(fName1) || !record.count(fName2)) cout << "NA\n";
else if (record[fName1].first == record[fName2].first) cout << "Whatever\n";
else cout << check(fName1, fName2) << endl;
}
return 0;
}
L2-031 深入虎穴
#include <bits/stdc++.h>
using namespace std;
#define pii pair<int, int>
int N, K, D, one, vis[100001];
vector<int> Edge[100001];
queue<int> Q;
int main() {
cin >> N;
for (int i = 1; i <= N; ++i) {
cin >> K;
while(K--) {
cin >> D;
Edge[D].push_back(i);
Edge[i].push_back(D);
}
}
Q.push(1);
vis[1] = 1;
while(!Q.empty()) {
one = Q.front();
Q.pop();
for (auto v:Edge[one]) {
if (vis[v]) continue;
vis[v] = 1;
Q.push(v);
}
}
cout << one;
return 0;
}
L2-032 彩虹瓶
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
int stk[N];
int main()
{
int n, m, k; cin >> n >> m >> k;
for (int i = 0; i < k; i ++ )
{
bool flag = true;
int idx = -1, cnt = 1, x;
for (int j = 0; j < n; j ++ )
{
cin >> stk[++ idx];
while (idx >= 0 && stk[idx] == cnt) idx --, cnt ++ ;
if (idx + 1 > m)
{
flag = false;
// break;
}
}
if (idx == -1 && flag) puts("YES");
else puts("NO");
}
return 0;
}
/*
注意! 在这里不能直接break! 在这里我们是在输入时进行判断,即使你输入一部分就能判断NO,后面的数据依然要输入,等输入完才能进行判断,如果你提前终止,那么留在缓冲区的数据会影响会留给后面的cin接收,所以一定要等输入结束才能进行判断!
*/
L2-033 简单计算器
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
int n, in[N], res;
char op, record[N];
int main()
{
cin >> n;
for (int i = n - 1; i >= 0; i -- ) cin >> in[i];
for (int i = n - 1; i > 0; i -- ) cin >> record[i];
res = in[0];
for (int i = 1; i <= n - 1; i ++ )
{
op = record[i];
if (op == '+') res = in[i] + res;
else if (op == '-') res = in[i] - res;
else if (op == '*') res = in[i] * res;
else
{
if (res == 0)
{
printf("ERROR: %d/0\n", in[i]);
return 0;
}
res = in[i] / res;
}
}
cout << res << endl;
return 0;
}
L2-034 口罩发放
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <unordered_map>
#include <set>
using namespace std;
const int N = 10010;
struct node {
string name, id, time;
int isIll, order;
};
bool isLegal(const string &s)
{
if (s.size() != 18) return false;
for (auto it : s) if (!isdigit(it)) return false;
return true;
}
// 容器结构体排序用const
bool cmp(const node &a, const node &b)
{
if (a.time != b.time) return a.time < b.time;
return a.order < b.order;
}
int D, P, S, T, providedNum;
vector<node> record, ill;
unordered_map<string, int> lastGet;
set<string> gotten;
int main()
{
cin >> D >> P;
for (int i = 1; i <= D; i ++ )
{
cin >> T >> S;
record.resize(T);
providedNum = 0;
// 先对每一组的记录进行处理输出, 同时将状态为1的用户添加到ill中, 最后进行输出
for (int j = 0; j < T; j ++ )
{
cin >> record[j].name >> record[j].id >> record[j].isIll >> record[j].time;
record[j].order = j;
if (!isLegal(record[j].id)) record[j].name = "";
else
{
// 添加 ill 信息
if (!lastGet.count(record[j].id)) lastGet[record[j].id] = -100;
if (record[j].isIll == 1 && !gotten.count(record[j].id) )
{
ill.push_back(record[j]);
gotten.insert(record[j].id);
}
}
}
sort(record.begin(), record.end(), cmp);
for (int j = 0; j < T && providedNum < S; j ++ )
{
if (record[j].name != "" && i - lastGet[record[j].id] > P)
{
lastGet[record[j].id] = i;
providedNum ++ ;
cout << record[j].name << " " << record[j].id << endl;
}
}
}
for (auto it : ill) cout << it.name << " " << it.id << endl;
return 0;
}
L2-035 完全二叉树的层序遍历
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 50;
int n, idx, post[N], lev[N];
// 后序 -> 层序 下标表示了层序遍历的顺序
void level(int i)
{
if (i > n) return;
level(i << 1);
level(i << 1 | 1);
lev[i] = post[idx ++ ];
}
int main()
{
cin >> n;
for (int i = 0; i < n; i ++ ) cin >> post[i];
level(1);
cout << lev[1];
for (int i = 2; i <= n; i ++ ) cout << " " << lev[i];
return 0;
}
L2-036 网红点打卡攻略
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 210, INF = 0x3f3f3f3f;
int n, m, k, g[N][N], cnt[N], path[N];
int main()
{
cin >> n >> m;
int a, b, c;
memset(g, INF, sizeof g);
for (int i = 0; i < m; i ++ )
{
cin >> a >> b >> c;
g[a][b] = g[b][a] = c;
}
cin >> k;
int mincost = INF, id = -1, num = 0;
for (int i = 1; i <= k; i ++ )
{
int u, cost = 0;
path[0] = path[n + 1] = 0;
cin >> u;
bool flag = false;
memset(cnt, 0, sizeof cnt);
for (int j = 1; j <= u; j ++ )
{
cin >> path[j];
if (cnt[path[j]]) path[0] ++ ;
cnt[path[j]] ++ ;
}
if (u != n || path[0]) continue;
for (int j = 1; j <= n + 1; j ++ )
{
if (g[path[j]][path[j - 1]] == INF)
{
flag = true;
break;
}
cost += g[path[j]][path[j - 1]];
}
if (flag) continue;
num ++ ;
if (cost < mincost)
{
id = i;
mincost = cost;
} else if (cost == mincost) {
id = min(id, i);
}
}
cout << num << endl << id << " " << mincost << endl;
return 0;
}
/// 另一种做法
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = 10010;
vector<int> child[maxn];
//目前序列和结果序列
vector<int> path, ans;
int father[maxn];
int n, k;
int temp;
int maxDepth = 0;
void DFS(int s, int depth)
{
if (child[s].size() == 0)
{
if (depth > maxDepth)
{
maxDepth = depth;
ans = path;
}
return;
}
for (int i = 0; i < child[s].size(); i++)
{
path.push_back(child[s][i]);
DFS(child[s][i], depth + 1);
//记得回退
path.pop_back();
}
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
father[i] = i;
for (int i = 0; i < n; i++)
{
cin >> k;
for (int j = 0; j < k; j++)
{
cin >> temp;
child[i].push_back(temp);
father[temp] = i;
}
//排序
if (child[i].size() != 0)
sort(child[i].begin(), child[i].end(), less<int>());
}
int root;
for (int i = 0; i < n; i++)
{
if (father[i] == i)
root = father[i];
}
// cout << root << endl;
path.push_back(root);
DFS(root, 1);
cout << maxDepth << endl;
// cout << ans.size() << endl;
for (int i = 0; i < ans.size(); i++)
{
cout << ans[i];
if (i != ans.size() - 1)
cout << " ";
}
return 0;
}
L2-037 包装机
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
const int N = 1010;
queue<char> q[N];
stack<char> stk;
int main()
{
int n, m, smax; cin >> n >> m >> smax;
string s;
for (int i = 1; i <= n; i ++ )
{
cin >> s;
for (int j = 0; j < s.size(); j ++ ) q[i].push(s[j]);
}
int op;
while (cin >> op)
{
if (op == -1) break;
if (op == 0)
{
if (stk.empty()) continue;
cout << stk.top();
stk.pop();
} else {
if (q[op].empty()) continue;
if (stk.size() == smax)
{
cout << stk.top();
stk.pop();
}
stk.push(q[op].front());
q[op].pop();
}
}
return 0;
}
L2-038 病毒溯源
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 10010;
bool st[N];
int lev = -1, p[N], id = -1;
void dfs(int u, int v, vector<vector<int> > &vv)
{
if (v > lev)
{
lev = v;
id = u;
}
for (auto t : vv[u])
{
dfs(t, v + 1, vv);
}
}
int main()
{
int n, k, x; cin >> n;
vector<vector<int> > v(n);
memset(p, -1, sizeof p);
for (int i = 0; i < n; i ++ )
{
cin >> k;
for (int j = 0; j < k; j ++ )
{
cin >> x;
p[x] = i;
st[x] = true;
v[i].push_back(x);
}
sort(v[i].begin(), v[i].end());
}
int fi = -1;
for (int i = 0; i < n; i ++ )
if (!st[i]) fi = i;
dfs(fi, 1, v);
cout << lev << endl;
vector<int> ans;
while (id != fi)
{
ans.push_back(id);
id = p[id];
}
ans.push_back(id);
cout << ans[ans.size() - 1];
for (int i = ans.size() - 2; i >= 0; i -- )
{
cout << " " << ans[i];
}
return 0;
}
L2-039 清点代码库
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
const int N = 10010;
int n, m, t;
vector<int> tmp;
map<vector<int>, int> A;
multimap<int, vector<int>, greater<int>> B; // multimap - 允许存在重复键
int main()
{
cin >> n >> m;
tmp.resize(m);
for (int i = 0; i < n; i ++ )
{
for (int j = 0; j < m; j ++ ) cin >> tmp[j];
A[tmp] ++ ;
}
for (auto it : A) B.insert({it.second, it.first});
cout << A.size() << endl;
for (auto it : B)
{
cout << it.first;
for (auto it2 : it.second) cout << " " << it2;
cout << endl;
}
return 0;
}
L2-040 哲哲打游戏
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 100010;
vector<int> v[N];
int archive[110];
int main()
{
int n, m, k; cin >> n >> m;
int x;
for (int i = 1; i <= n; i ++ )
{
cin >> k;
for (int j = 1; j <= k; j ++ )
{
cin >> x;
v[i].push_back(x);
}
}
int op, idx = 1;
for (int i = 1; i <= m; i ++ )
{
cin >> op >> x;
if (op == 0)
{
idx = v[idx][x - 1];
} else if (op == 1) {
archive[x] = idx;
cout << idx << endl;
} else {
idx = archive[x];
}
}
cout << idx << endl;
return 0;
}
L3
L3-001 凑零钱
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 10010;
int f[N], w[N]; // 一维滚动数组
bool st[N][N];
int cmp(int a, int b) {return a > b; }
int main()
{
int n, m; cin >> n >> m;
for (int i = 1; i <= n; i ++ ) cin >> w[i];
sort(w + 1, w + n + 1, cmp);
for (int i = 1; i <= n; i ++ )
for (int j = m; j >= w[i]; j -- )
if (f[j] <= f[j - w[i]] + w[i]) {
st[i][j] = true; // 选取
f[j] = f[j - w[i]] + w[i];
}
if (f[m] != m) puts("No Solution");
else {
vector<int> res;
int v = m, idx = n;
while (v > 0) {
if (st[idx][v]) {
res.push_back(w[idx]);
v -= w[idx];
}
idx -- ;
}
for (int i = 0; i < res.size(); i ++ ) {
cout << res[i];
if (i == res.size() - 1) cout << endl;
else cout << " ";
}
}
return 0;
}
L3-003 社交集群
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
int p[N], f[N], root[N]; // f 为喜欢第i个编号的人
int cmp(int a, int b) {return a > b; }
int find(int x)
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
void Union(int a, int b)
{
p[find(a)] = find(b);
}
int main()
{
int n, k, t, cnt = 0;
scanf("%d", &n);
for (int i = 1; i <= n; i ++ ) p[i] = i;
for (int i = 1; i <= n; i ++ ) {
scanf("%d:", &k);
for (int j = 1; j <= k; j ++ )
{
scanf("%d", &t);
if (f[t] == 0) f[t] = i;
Union(i, find(f[t]));
}
}
for (int i = 1; i <= n; i ++ ) root[find(i)] ++ ;
for (int i = 1; i <= n; i ++ ) {
if (root[i]) cnt ++ ;
}
printf("%d\n", cnt);
sort(root, root + N, cmp);
for (int i = 0; i < cnt; i ++ ) {
printf("%d", root[i]);
if (i == cnt - 1) printf("\n");
else printf(" ");
}
return 0;
}
L3-004 肿瘤诊断
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 1010;
struct node {
int x, y, z;
};
int m, n, l, t;
int dx[6] = {1, 0, 0, -1, 0, 0};
int dy[6] = {0, 1, 0, 0, -1, 0};
int dz[6] = {0, 0, 1, 0, 0, -1};
int g[1300][130][80];
bool st[1300][130][80];
bool judge(int x, int y, int z) {
if (x < 0 || x >= m || y < 0 || y >= n || z < 0 || z >= l) return false;
if (g[x][y][z] == 0 || st[x][y][z]) return false;
return true;
}
int bfs(int x, int y, int z) {
int cnt = 0;
node tmp;
tmp.x = x, tmp.y = y, tmp.z = z;
queue<node > q;
q.push(tmp);
st[x][y][z] = true;
while (!q.empty()) {
node top = q.front(); q.pop();
cnt ++ ;
for (int i = 0; i < 6; i ++ ) {
int tx = top.x + dx[i];
int ty = top.y + dy[i];
int tz = top.z + dz[i];
if (judge(tx, ty, tz)) {
st[tx][ty][tz] = true;
tmp.x = tx, tmp.y = ty, tmp.z = tz;
q.push(tmp);
}
}
}
if (cnt >= t) return cnt;
else return 0;
}
int main()
{
cin >> m >> n >> l >> t;
// 注意输入的顺序
for (int i = 0; i < l; i ++ )
for (int j = 0; j < m; j ++ )
for (int k = 0; k < n; k ++ )
cin >> g[j][k][i];
int res = 0;
for (int i = 0; i < l; i ++ )
for (int j = 0; j < m; j ++ )
for (int k = 0; k < n; k ++ )
if (g[j][k][i] && !st[j][k][i]) {
res += bfs(j, k, i);
}
cout << res << endl;
return 0;
}
L3-005 垃圾箱分布
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
const int inf = 999999999;
int n, m, k, ds, station;
int e[1020][1020], dis[1020];
bool visit[1020];
int main() {
fill(e[0], e[0] + 1020 * 1020, inf);
fill(dis, dis + 1020, inf);
scanf("%d%d%d%d", &n, &m, &k, &ds);
for(int i = 0; i < k; i++) {
int tempdis;
string s, t;
cin >> s >> t >> tempdis;
int a, b;
if(s[0] == 'G') {
s = s.substr(1);
a = n + stoi(s);
} else {
a = stoi(s);
}
if(t[0] == 'G') {
t = t.substr(1);
b = n + stoi(t);
} else {
b = stoi(t);
}
e[a][b] = tempdis;
e[b][a] = tempdis;
}
int ansid = -1;
double ansdis = -1, ansaver = inf;
for(int index = n + 1; index <= n + m; index++) {
double mindis = inf, aver = 0;
fill(dis, dis + 1020, inf);
fill(visit, visit + 1020, false);
dis[index] = 0;
for(int i = 0; i < n + m; i++) {
int u = -1, minn = inf;
for(int j = 1; j <= n + m; j++) {
if(visit[j] == false && dis[j] < minn) {
u = j;
minn = dis[j];
}
}
if(u == -1) break;
visit[u] = true;
for(int v = 1; v <= n + m; v++) {
if(visit[v] == false && dis[v] > dis[u] + e[u][v])
dis[v] = dis[u] + e[u][v];
}
}
for(int i = 1; i <= n; i++) {
if(dis[i] > ds) {
mindis = -1;
break;
}
if(dis[i] < mindis) mindis = dis[i];
aver += 1.0 * dis[i];
}
if(mindis == -1) continue;
aver = aver / n;
if(mindis > ansdis) {
ansid = index;
ansdis = mindis;
ansaver = aver;
} else if(mindis == ansdis && aver < ansaver) {
ansid = index;
ansaver = aver;
}
}
if(ansid == -1)
printf("No Solution");
else {
printf("G%d\n", ansid - n);
printf("%.1f %.1f", ansdis, ansaver);
}
return 0;
}
L3-007 天梯地图
L3-008 喊山
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
const int N = 10010;
vector<vector<int> > g(N);
bool st[N];
int lev[N];
int bfs(int t)
{
memset(st, false, sizeof st);
memset(lev, 0, sizeof lev);
int maxlev = -1, id = N;
queue<int> q;
q.push(t);
st[t] = true;
while (!q.empty()) {
int h = q.front(); q.pop();
if (lev[h] > maxlev) {
maxlev = lev[h];
id = N;
}
if (h != t)
id = min(id, h);
for (int i = 0; i < g[h].size(); i ++ ) {
if (!st[g[h][i]]) {
st[g[h][i]] = true;
q.push(g[h][i]);
lev[g[h][i]] = lev[h] + 1;
}
}
}
if (id != N) return id;
else return 0;
}
int main()
{
int n, m, k; cin >> n >> m >> k;
int a, b;
for (int i = 0; i < m; i ++ ) {
cin >> a >> b;
g[a].push_back(b);
g[b].push_back(a);
}
int t;
for (int i = 0; i < k; i ++ ) {
cin >> t;
cout << bfs(t) << endl;
}
return 0;
}
L3-010 是否完全二叉搜索树
#include <cstdio>
using namespace std;
int tree[1<<20];
int num;
void BST(int a) {
if(tree[a] == 0)
tree[a] = num;
else if(tree[a] < num)
BST(a<<1);
else
BST(a<<1|1);
}
int main() {
int n;
scanf("%d", &n);
for(int i = 0; i < n; i++) {
scanf("%d", &num);
BST(1);
}
bool flag = true;
for(int cnt = 1, k = 1; cnt <= n; k++) {
if(tree[k] == 0)
flag = false;
else {
printf("%d", tree[k]);
if(cnt++ != n) printf(" ");
}
}
if(flag) printf("\nYES");
else printf("\nNO");
return 0;
}
L3-011 直捣黄龙
L3-014 周游世界
L3-015 球队“食物链”
L3-016 二叉搜索树的结构
L3-018 森森美图
L3-019 代码排版 (模拟)
L3-022 地铁一日游
L3-028 森森旅游
L3-029 还原文件