文章目录
- 1001 A+B Format (20 分)
- 1002 A+B for Polynomials (25 分)
- 1003 Emergency (25 分)
- 1004 Counting Leaves (30 分)
- 1005 Spell It Right (20 分)
- 1006 Sign In and Sign Out (25 分)
- 1007 Maximum Subsequence Sum (25 分)
- 1008 Elevator (20 分)
- 1009 Product of Polynomials 分数 25
- 1010 Radix 分数 25
- 1011 World Cup Betting 分数 20
- 1012 The Best Rank 分数 25
- 1013 Battle Over Cities 分数 25
- 1014 Waiting in Line 分数 30
- 1015 Reversible Primes 分数 20
- 1016 Phone Bills 分数 25
- 1017 Queueing at Bank 分数 25
1001 A+B Format (20 分)
- 题意:给定两个整数a和b,返回答案a+b要求千位分隔符
/*made in zzh*/
#include <bits/stdc++.h>
using namespace std;
string solve(string s)
{
reverse(s.begin(), s.end());
string ans = "";
int n = s.size();
int cnt = 0;
for (int i = 0; i < n; i++)
{
ans += (s[i]);
if (++cnt % 3 == 0 && i != (n - 1))
ans += ",";
}
reverse(ans.begin(), ans.end());
return ans;
}
signed main()
{
int a, b;
cin >> a >> b;
if (a + b < 0)
cout << "-";
cout << solve(to_string(abs(a + b)));
}
1002 A+B for Polynomials (25 分)
1002 A+B for Polynomials (25 分)
- 题意:多项式相加,共两行输入,每一行第一个数字是项数,之后每两个数字a和b构成一个ab,然后要求输出两个多项式相加的答案
/*made in zzh*/
#include <bits/stdc++.h>
using namespace std;
struct cmp
{
bool operator()(const int &x, const int &y)
{
return x > y;
}
};
map<int, double, cmp> mp;
int n, x, Ans = 0;
double y;
void solve(int n)
{
while (n--)
{
cin >> x >> y;
mp[x] += y;
}
}
signed main()
{
cin >> n;
solve(n);
cin >> n;
solve(n);
for (auto t : mp)
if (t.second)
Ans++;
cout << Ans;
for (auto t : mp)
if (t.second)
printf(" %d %.1f", t.first, t.second);
}
1003 Emergency (25 分)
- 题意:给定n,m,s,t分别为总点数,总边数,起点,终点,然后一行输入每一个城市的人数,之后m行输入每一条边,询问时s->t的最短路径的数量和在所有最短路径中可以召集的最多人数
/*made in zzh*/
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = 2e5 + 10, M = N * 2;
int dist[N], vis[N], peo[N], sum[N];
int ne[M], e[M], h[N], w[N], idx;
void add(int u, int v, int c)
{
e[idx] = v;
ne[idx] = h[u];
w[idx] = c;
h[u] = idx++;
}
int perple[N];
void dij(int s, int t)
{
memset(dist, 0x3f, sizeof dist);
dist[s] = 0;
peo[s] = perple[s];
sum[s] = 1;
priority_queue<PII, vector<PII>, greater<PII>> que;
que.push({dist[s], s});
while (que.size())
{
PII q = que.top();
que.pop();
int ver = q.second, distance = q.first;
if (vis[ver])
continue;
vis[ver] = 1;
for (int i = h[ver]; i != -1; i = ne[i])
{
int j = e[i];
if (dist[j] > dist[ver] + w[i])
{
dist[j] = dist[ver] + w[i];
peo[j] = perple[j] + peo[ver];
que.push(make_pair(dist[j], j));
sum[j] = sum[ver];
}
else if ((dist[j] == dist[ver] + w[i]))
{
sum[j] += sum[ver];
if (peo[j] < peo[ver] + perple[j])
{
peo[j] = peo[ver] + perple[j];
que.push(make_pair(dist[j], j));
}
}
}
}
}
signed main()
{
int n, m, s, t;
cin >> n >> m >> s >> t;
for (int i = 0; i < n; i++)
{
h[i] = -1;
cin >> perple[i];
}
while (m--)
{
int u, v, w;
cin >> u >> v >> w;
add(u, v, w);
add(v, u, w);
}
dij(s, t);
cout << sum[t] << " " << peo[t];
}
1004 Counting Leaves (30 分)
- 题意:给定一棵树,输入n,m分别为树的总点数和非叶子节点数,之后m行输入第一个数是父亲节点编号,第二个数cnt为儿子节点,然后cnt个结点为儿子节点的编号,询问每一个深度的叶子节点数量
/*made in zzh*/
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, M = N;
int h[N], e[M], ne[M], idx;
void add(int u, int v)
{
e[idx] = v;
ne[idx] = h[u];
h[u] = idx++;
}
int va[N], Max_depth;
void dfs(int u, int depth)
{
Max_depth = max(Max_depth, depth);
if (h[u] == -1)
{
va[depth]++;
return;
}
for (int i = h[u]; i != -1; i = ne[i])
{
int j = e[i];
dfs(j, depth + 1);
}
}
signed main()
{
int n, m;
cin >> n >> m;
memset(h, -1, sizeof h);
for (int i = 0; i < m; i++)
{
int u, v, num;
cin >> u >> num;
while (num--)
{
cin >> v;
add(u, v);
}
}
dfs(1, 0);
cout << va[0];
for (int i = 1; i <= Max_depth; i++)
cout << " " << va[i];
}
1005 Spell It Right (20 分)
- 题意:输入一个整数a<10100,询问每一位的数字相加的和,用英文输出
/*made in zzh*/
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
map<int, string> mp;
string s[N] = {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "zero"};
signed main()
{
for (int i = 1; i <= 10; i++)
mp[i % 10] = s[i - 1];
string s;
cin >> s;
int ans = 0;
for (int i = 0; i < s.size(); i++)
ans += (s[i] - '0');
s = to_string(ans);
cout<<mp[s[0] - '0'];
for (int i = 1; i < s.size(); i++)
cout <<" "<< mp[s[i] - '0'];
}
1006 Sign In and Sign Out (25 分)
1006 Sign In and Sign Out (25 分)
- 题意:给定n行字符串,每一行分别是人名,到达时间,离开时间,询问最早到达和最晚离开的人名
/*made in zzh*/
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
string a, b;
string AA = "25", BB = "00:00:00";
signed main()
{
int n;
cin >> n;
while (n--)
{
string name, time_arrive, time_leave;
cin >> name >> time_arrive >> time_leave;
if (AA > time_arrive)
{
AA = time_arrive;
a = name;
}
if (BB < time_leave)
{
BB = time_leave;
b = name;
}
}
cout << a << " " << b;
}
1007 Maximum Subsequence Sum (25 分)
1007 Maximum Subsequence Sum (25 分)
- 题意:输入n个数,询问最大连续子序列的和,该序列的第一个数和最后一个数
/*made in zzh*/
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
int a[N], dp[N], pre[N];
signed main()
{
int n, f = 0;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
if (a[i] >= 0)
f = 1;
}
if (!f)
return cout << 0 << " " << a[1] << " " << a[n], 0;
for (int i = 1; i <= n; i++)
{
if (a[i] < dp[i - 1] + a[i])
{
dp[i] = dp[i - 1] + a[i];
pre[i] = pre[i - 1];
}
else
{
dp[i] = a[i];
pre[i] = i;
}
}
int M = -1;
for (int i = 1; i <= n; i++)
{
if (M < dp[i])
{
f = i;
M = dp[i];
}
}
cout << dp[f] << " " << a[pre[f]] << " " << a[f];
}
1008 Elevator (20 分)
- 题意:给定一个整数n,每上一步需要6s 下一步需要4s 每一次停止再启动需要5s的时间,起始点是0,询问总共多少s
/*made in zzh*/
#include <bits/stdc++.h>
using namespace std;
signed main()
{
int n, x, now, ans = 0;
cin >> n;
while (n--)
{
int x;
cin >> x;
if (x > now)
ans += (x - now) * 6 + 5;
else
ans += (now - x) * 4 + 5;
now = x;
}
cout << ans << endl;
}
1009 Product of Polynomials 分数 25
1009 Product of Polynomials 分数 25
- 题意:给定两个多项式,首先是整数n,后面n对(e,c)分别表示多项式的指数和系数。求解两个多项式相乘结果
#include <bits/stdc++.h>
using namespace std;
vector<double> a(1010, 0), b(1010, 0), c(2010, 0);
vector<pair<int, double>> ans;
signed main()
{
int n, m;
cin >> n;
while (n--)
{
int e;
double c;
cin >> e >> c;
a[e] = c;
}
cin >> m;
while (m--)
{
int e;
double c;
cin >> e >> c;
b[e] = c;
}
for (int i = 0; i <= 1000; i++)
for (int j = 0; j <= 1000; j++)
c[i + j] += (a[i] * b[j]);
int sum = 0;
for (int i = 0; i <= 2010; i++)
if (c[i] != 0)
{
sum++;
ans.push_back(make_pair(i, c[i]));
}
reverse(ans.begin(), ans.end());
cout << sum;
for (auto t : ans)
printf(" %d %.1f", t.first, t.second);
}
1010 Radix 分数 25
- 题意:给定两个字符串,如果op为1,最后一个数就是第一个字符串的进制数,否则是第二个进制数,问是否存在最小的可以使s1 == s2的进制数
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int INF = 1e18;
int solve(string s, int j)
{
int sum = 0;
int len = s.size();
for (int i = 0; i < len; i++)
{
if (sum >= INF / j)
return INF;
if (s[i] <= '9' && s[i] >= '0')
sum = sum * j + s[i] - '0';
else
sum = sum * j + s[i] - 'a' + 10;
}
if (sum < 0)
return INF;
return sum;
}
int wor(string s)
{
int ans = 0;
int len = s.size();
for (int i = 0; i < len; i++)
{
if (s[i] <= '9' && s[i] >= '0')
ans = max(ans, (int)s[i] - '0');
else
ans = max(ans, (int)s[i] - 'a' + 10);
}
return ans + 1;
}
signed main()
{
int b = 0;
string s1, s2;
int op, tag;
cin >> s1 >> s2 >> op >> tag;
if (op == 2)
swap(s1, s2);
int a = solve(s1, tag);
int l = wor(s2);
int r = max(l, a + 1);
while (l < r)
{
int mid = (l + r) / 2;
if (solve(s2, mid) >= a)
r = mid;
else
l = mid + 1;
}
if (solve(s2, l) == a)
cout << l << endl;
else
cout << "Impossible\n";
}
1011 World Cup Betting 分数 20
- 题意:公式(max×65%−1)×2,输入就是三行,找每一行最大值,*起来带入max输出就行,数字顺序是W T L
#include <bits/stdc++.h>
using namespace std;
const int N = 2e3 + 10;
int cnt[5];
signed main()
{
map<int, string> mp;
mp[0] = "W";
mp[1] = "T";
mp[2] = "L";
double ans = 1;
for (int i = 0; i < 3; i++)
{
double c = -10000;
for (int j = 0; j < 3; j++)
{
double x;
cin >> x;
c = max(c, x);
if (c == x)
cnt[i] = j;
}
ans *= c;
}
for (int i = 0; i < 3; i++)
cout << mp[cnt[i]] << " ";
printf("%.2f", (ans * 0.65 - 1) * 2);
}
1012 The Best Rank 分数 25
- 题意:给定n行ID名,C,M,E。A定义为C,M和E的平均值,排序的优先级为A>C>M>E,然后查找对应ID的最高排名,有并列特判。
#include <bits/stdc++.h>
using namespace std;
const int N = 2010;
struct node
{
int id;
double score[5];
int ans = 10;
string S;
} a[N];
map<int, string> mp = {
{0, "A"},
{1, "C"},
{2, "M"},
{3, "E"}};
int now = 0;
bool cmp(node a, node b)
{
return a.score[now] > b.score[now];
}
signed main()
{
int n, m;
cin >> n >> m;
for (int i = 0; i < n; i++)
{
cin >> a[i].id >> a[i].score[1] >> a[i].score[2] >> a[i].score[3];
a[i].score[0] = (a[i].score[1] + a[i].score[2] + a[i].score[3]) / 3.0;
}
for (; now < 4; now++)
{
sort(a, a + n, cmp);
for (int i = 0; i < n; i++)
{
// 可以直接将前面的继承过来
int rank = i;
while (rank--)
if (a[i].score[now] != a[rank].score[now])
break;
if (rank + 2 < a[i].ans)
{
a[i].ans = rank + 2;
a[i].S = mp[now];
}
}
}
while (m--)
{
int id, flag = 0;
cin >> id;
for (int i = 0; i < n; i++)
if (a[i].id == id)
{
cout << a[i].ans << " " << a[i].S << endl;
flag = 1;
break;
}
if (!flag)
cout << "N/A\n";
}
}
1013 Battle Over Cities 分数 25
- 题意:给定n个点,m条路,k个询问,询问是删除编号id的点,为了使图联通需要新增几条路
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10, M = 2 * N * N;
int h[N], e[M], ne[M], idx;
int st[N];
void add(int u, int v)
{
e[idx] = v;
ne[idx] = h[u];
h[u] = idx++;
}
void dfs(int u)
{
for (int i = h[u]; i != -1; i = ne[i])
{
int j = e[i];
if (st[j] == -1 || st[j] == 1)
continue;
st[j] = 1;
dfs(j);
}
}
signed main()
{
int n, m, k;
cin >> n >> m >> k;
for (int i = 1; i <= n; i++)
h[i] = -1;
for (int i = 0; i < m; i++)
{
int u, v;
cin >> u >> v;
add(u, v);
add(v, u);
}
while (k--)
{
int ans = 0;
memset(st, 0, sizeof st);
int x;
cin >> x;
st[x] = -1;
for (int i = 1; i <= n; i++)
{
if (i == x)
continue;
if (st[i] == 0)
{
dfs(i);
ans++;
}
}
cout << ans - 1 << "\n";
}
}
1014 Waiting in Line 分数 30
- 题意:n个窗口,每一个窗口可以排队m人,总共k个人,每一个人需求时是正整数,然后q次询问。排队规则是队伍人数一样长的时候,排编号最小的队伍,否则去队伍人数最少的队伍排队。然后对于17:00之后的请求不再处理,只处理[8:00,17:00)之间的请求,而且如果处理完成时间大于17:00,也要给出一个目标时间(一定合法,不会超级大)。
1015 Reversible Primes 分数 20
- 题意:给定10进制数字n,d,判断10进制n和反转后的d进制的n是否为素数。
#include <bits/stdc++.h>
using namespace std;
#define int long long
int solve(string a, int b) // 将b进制的a 转化成10进制的now
{
int now = 0;
for (int i = 0; i < (int)a.size(); i++)
now = now * b + a[i] - '0';
return now;
}
string solve_tran(int a, int b) // 将10进制的a 转化成b进制的now
{
string now = "";
while (a)
{
now += to_string(a % b);
a /= b;
}
return now;
}
int isprime(int a)
{
int m = sqrt(a);
for (int i = 2; i <= m; i++)
if (a % i == 0)
return 0;
return !(a == 1);
}
signed main()
{
string n;
int d;
while (cin >> n >> d)
{
if (n[0] == '-')
break;
string c = solve_tran(atoll(n.c_str()), d);
int p = solve(c, d);
if (isprime(atoll(n.c_str())) && isprime(p))
cout << "Yes\n";
else
cout << "No\n";
}
}
1016 Phone Bills 分数 25
- 题意:给定24小时的价格,单位是美分/分钟,然后给定n个任务(无序),首先是任务的受理人,之后是任务的发生时间,最后是任务的类型,on-line是开始,off-line是结束,同时会存在非法任务,对于多次任务的开始,只记录最后一次,对于多次任务的结束,只记录最初一次。问每一个受理人的使用时间和价钱,价钱为0的受理人不输出。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 5e4 + 10;
int money[30], SUM[N], n, month;
map<string, vector<string>> mp;
int solve(string a, string b)
{
int d = atoll(a.substr(0, 2).c_str()), d1 = atoll(b.substr(0, 2).c_str());
int h = atoll(a.substr(0 + 3, 2).c_str()), h1 = atoll(b.substr(0 + 3, 2).c_str());
int m = atoll(a.substr(0 + 6, 2).c_str()), m1 = atoll(b.substr(0 + 6, 2).c_str());
return ((d - d1) * 60 * 24 + (h - h1) * 60 + (m - m1));
}
double work(string a, string b)
{
int d = atoll(a.substr(0, 2).c_str()), d1 = atoll(b.substr(0, 2).c_str());
int h = atoll(a.substr(0 + 3, 2).c_str()), h1 = atoll(b.substr(0 + 3, 2).c_str());
int m = atoll(a.substr(0 + 6, 2).c_str()), m1 = atoll(b.substr(0 + 6, 2).c_str());
return (double)(SUM[(d)*60 * 24 + (h)*60 + m] - SUM[(d1)*60 * 24 + (h1)*60 + m1]);
}
struct node
{
string name, val, op;
} a[N];
bool cmp(node a, node b)
{
return a.val < b.val;
}
signed main()
{
for (int i = 1; i <= 24; i++)
cin >> money[i];
for (int i = 1; i <= 31; i++) // 利用前缀和进行预处理
for (int j = 1; j <= 24; j++)
for (int k = 1; k <= 60; k++)
SUM[(i - 1) * 60 * 24 + (j - 1) * 60 + k] = SUM[(i - 1) * 60 * 24 + (j - 1) * 60 + k - 1] + money[j];
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> a[i].name;
scanf("%lld:", &month);
cin >> a[i].val >> a[i].op;
}
sort(a, a + n, cmp);
for (int i = 0; i < n; i++)
if (a[i].op == "on-line")
{
if (mp[a[i].name].size() % 2)
mp[a[i].name].back() = a[i].val;
else
mp[a[i].name].push_back(a[i].val);
}
else if (a[i].op == "off-line" && (mp[a[i].name].size() % 2))
mp[a[i].name].push_back(a[i].val);
for (auto t : mp)
{
vector<string> now = t.second;
double sum = 0;
for (int i = 0; i + 1 < (int)now.size(); i += 2)
sum += work(now[i + 1], now[i]);
if (sum > 0)
{
cout << t.first << " ";
if (month < 10)
cout << "0";
cout << month << endl;
for (int i = 0; i + 1 < (int)now.size(); i += 2)
{
cout << now[i] << " " << now[i + 1] << " " << solve(now[i + 1], now[i]) << " ";
printf("$%.2f\n", work(now[i + 1], now[i]) / 100.00);
}
printf("Total amount: $%.2f\n", sum / 100.00);
}
}
}
1017 Queueing at Bank 分数 25
- 题意:给定n个任务,每一行给出开始时间,持续时间,仅有k个机器可以运行任务,询问平均等待时间。机器工作时间是8点到17点,17点之后到达的任务不再运行。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e4 + 10;
int sub(string a, string b)
{
int d = atoll(a.substr(0, 2).c_str()), d1 = atoll(b.substr(0, 2).c_str());
int h = atoll(a.substr(0 + 3, 2).c_str()), h1 = atoll(b.substr(0 + 3, 2).c_str());
int m = atoll(a.substr(0 + 6, 2).c_str()), m1 = atoll(b.substr(0 + 6, 2).c_str());
return ((d - d1) * 60 * 60 + (h - h1) * 60 + (m - m1));
}
string To_string(int s)
{
if (s < 10ll)
return ("0" + to_string(s));
return to_string(s);
}
string solve(string a, int b)
{
int h = atoll(a.substr(0, 2).c_str());
int m = atoll(a.substr(0 + 3, 2).c_str());
int s = atoll(a.substr(0 + 6, 2).c_str());
h += ((m + b) / 60);
m = (m + b) % 60;
return (To_string(h) + ":" + To_string(m) + ":" + To_string(s));
}
struct node
{
string t;
int p;
} a[N];
bool cmp(node a, node b)
{
return a.t < b.t;
}
signed main()
{
int n, k, ans = 0;
cin >> n >> k;
for (int i = 0; i < n; i++)
cin >> a[i].t >> a[i].p;
sort(a, a + n, cmp);
priority_queue<string, vector<string>, greater<string>> que;
for (int i = 0; i < n; i++)
{
if (a[i].t < "08:00:00")
{
ans += sub("08:00:00", a[i].t);
a[i].t = "08:00:00";
}
if (a[i].t >= "17:00:01")
{
n = i;
break;
}
if (que.size() < k)
que.push(solve(a[i].t, a[i].p));
else
{
string now = que.top();
que.pop();
if (now > a[i].t)
ans += (sub(now, a[i].t));
que.push(solve(max(now, a[i].t), a[i].p));
}
}
printf("%.1f\n", round(ans / 6.0 / n) / 10.0);
}