前三个题目花了一个小时,挺顺利的,都是过了样例一边提交满分,最后一道题目花了巨长的时间,原因是一处细节错了,改正后只有22分,直到最后才解决。100!
之前从来没用过Floyd算法,差点忘了,不过很好写,记住就行了!
void floyd()
{
for (int k = 0; k <= n; k ++ )
for (int i = 0; i <= n; i ++ )
for (int j = 0; j <= n; j ++ )
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
}
第一题是个简单模拟,理解清楚题目含义就行了。
第二题是一个链表的问题,可以使用vector取巧。
第三题是一个多叉树+DFS的问题,我一开始想的是并查集,但是发现树似乎更加容易。
第四题是一个多源最短路+模拟,很讨厌写这种大模拟。。。
下面给出这次的代码。
A
//理解了
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10, M = 110;
int n, m;
int a[N], cnt[N];
int main()
{
cin >> n >> m;
while(m --)
{
unordered_map<int, int> mp;
for(int i = 0; i < n; i++)
{
cin >> a[i];
mp[a[i]]++;
}
//找出最厉害的
vector<int> tmp;
int maxv = 0;
for(int i = 0; i < n; i++)
{
int tt = n - mp[a[i]];
if(tt > maxv)
{
maxv = tt;
tmp.clear();
tmp.push_back(i);
}
else if(tt == maxv) tmp.push_back(i);
}
for(auto t : tmp) cnt[t]++;
}
int maxv = 0, maxi = 0;
for(int i = 0; i < n; i++)
if(cnt[i] > maxv)
{
maxv = cnt[i];
maxi = i;
}
cout << maxi + 1 << endl;
return 0;
}
B
//理解题意了
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n;
int e[N], head, idx;
unordered_map<int, int> ne;
int idxs[N];
int main()
{
cin >> n;
for(int i = 0; i < n; i++)
{
int next;
cin >> next;
ne[next] = i;
}
vector<int> nodes;
int cnt = 0, i = -1;
while(cnt < n)
{
i = ne[i];
nodes.push_back(i);
cnt++;
}
reverse(nodes.begin(), nodes.end());
// for(auto t : nodes) cout << t << " ";
// cout << endl;
for(int i = 0; i < n; i++)
{
idxs[nodes[i]] = i + 1;
}
cout << idxs[0];
for(int i = 1; i < n; i++) cout << " " << idxs[i];
cout << endl;
return 0;
}
C
//理解了,用并查集吧,好吧,最后用的是DFS
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, m;
int h[N], e[N], ne[N], idx;
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
int cnt[N];
int dfs(int u)
{
int sz = 1;
for(int i = h[u]; i != -1; i = ne[i])
{
int j = e[i];
sz += dfs(j);
}
cnt[u] = sz;
return sz;
}
int main()
{
cin >> n;
memset(h, -1, sizeof h);
for(int i = 2; i <= n; i++)
{
int son = i;
int father;
cin >> father;
add(father, son);
}
dfs(1);
cin >> m;
while(m --)
{
int x;
cin >> x;
cout << cnt[x] << endl;
}
return 0;
}
D
//应该能做出来吧,还有2hours,就是好麻烦啊,肉眼可见的麻烦
#include<bits/stdc++.h>
using namespace std;
struct Package{
int deadline, Y, P;
};
const int N = 1e3 + 10;
int n, m, startTime;
int g[N][N], record[N];
Package packages[N];
int dist[N][N];
void floyd()
{
for (int k = 0; k <= n; k ++ )
for (int i = 0; i <= n; i ++ )
for (int j = 0; j <= n; j ++ )
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
}
int delivery[N];
void check(int &money, int &arrtime)
{
money = 0, arrtime = startTime;
//开始检查
for(int i = 1; i <= n; i++)
{
//到达b
int a = delivery[i - 1], b = delivery[i];
arrtime = arrtime + dist[a][b];
if(arrtime <= packages[b].deadline)
{
money += packages[b].Y;
}
else
{
money += (packages[b].Y - packages[b].P);
}
}
arrtime += dist[delivery[n]][0];
}
int main()
{
int hh, mm;//临时变量
scanf("%d %d %d:%d", &n, &m, &hh, &mm);
startTime = hh * 60 + mm;
for(int i = 1; i <= n; i++)
{
int h, m, y, p;
scanf("%d:%d %d %d", &h, &m, &y, &p);
packages[i] = {h * 60 + m, y, p};
}
memset(dist, 0x3f, sizeof dist);
for(int i = 0; i < m; i++)
{
int a, b, c;
cin >> a >> b >> c;
dist[a][b] = dist[b][a] = min(dist[a][b], c);
}
floyd();
int K;
cin >> K;
int max_money = -1e9, short_time = 1e9;
while(K--)
{
//读入,判断
bool flag = true;
memset(record, 0, sizeof record);
for(int i = 1; i <= n; i++)
{
cin >> delivery[i];
record[delivery[i]]++;
if(record[delivery[i]] >= 2)
{
flag = false;
break;
}
}
if(!flag) continue;//不能完全送达
int money, arrtime;
check(money, arrtime);
if(money > max_money)
{
max_money = money;
short_time = arrtime;
}
else if(money == max_money)
{
if(arrtime < short_time)
{
max_money = money;
short_time = arrtime;
}
}
}
printf("%d %02d:%02d\n", max_money, (short_time / 60) % 24, short_time % 60);
return 0;
}