0%

[题解]牛客练习赛69 ABC

A

题目描述

DK 想出一道超级没有素质的题

DK 给了你一个标准的时钟,初始时间在 12:00

每分钟分针会顺时针转动 6°,而时针会顺时针转动 0.5°

DK 想知道,t 分钟后,时针和分针的较小夹角的大小是多少

由于这题超级没有素质,所以你需要将答案四舍五入到整数

输入描述:

1
2
3
第一行一个整数 n,表示数据组数

第 2 ~ n+1行,每行一个整数 t,意义见题目描述

输出描述:

1
输出n行,每行一个整数,表示答案

题解

此题是模拟题,难点在于那个0.5,可以事先用 if else 判断再对结果进行调整,也可以直接用double来模拟,最后再四舍五入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#define Oo ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#include <bits/stdc++.h>
using namespace std;
#define PI acos(-1.0)
typedef long long ll;
int solve(int time)
{
double f=(int)(6*time)%360;
double h=time/2.0;
double t1=abs(f-h);
double t2=abs(360-t1);
int ans=ceil(min(t1, t2));
return ans;
}
int main()
{
Oo
int __;
cin>>__;
while(__--)
{
int t;cin>>t;
if (t==720)cout<<0 << endl;
else
cout << solve(t) << endl;
}
return 0;
}

B

题目描述

给你一个长度为 n 的序列,第 i 个数为 $a_i $

将这个序列分割成 i 个不重合的子串,从每个子串中取出最大的 j 个数作为这个分割方法的价值,记价值最大的分割方法的价值为 val(i,j)

但是金发少女 DK 觉得这太好算了,于是她要你求下面的柿子

​ $\sum_{i=1}^{x}\sum_{j=1}^{y}val(i,j)$

输入描述:

1
第一行输入一个正整数 n第二行输入 n 个正整数,第 i 个数表示 ai第三行输入两个正整数 x,y,含义如题中所示

输出描述:

1
一个数,表示答案

数据范围:

$1≤n≤10^5, 1\le a_i\le 10^9≤ai≤10^9, x\times y<=n$


题解

对于一个确定的 X,Y ,答案一定是可以取到前 $X\times Y$ 个最大的值,所以只需要排序,再维护一个前缀和。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#define Oo ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#include <bits/stdc++.h>
using` `namespace` `std;
#define PI acos(-1.0)
typedef` `long` `long` `ll;
ll a[100005];
ll temp[100005];
int` `main()
{
``Oo
``ll n; cin>>n;
``for` `(``int` `i=0; i<n; i++)cin>>a[i];
``sort(a, a+n, greater<ll>());
``ll x, y;cin>>x >> y;
``for` `(``int` `i=0; i<n; i++)
``{
``if` `(i==0)temp[i]=a[i];
``else` `temp[i]=temp[i-1]+a[i];
``}
``ll ans=0;
``for` `(``int` `i=1; i<=x; i++)
``{
``for` `(``int` `j=1; j<=y; j++)
``{
``ans+=temp[i*j-1];
``}
``}cout << ans << endl;
``return` `0;
}

C

题目描述

DK 有一个无向图 G,这个无向图有 n 个点 m 条边
你需要确定一个大小为 n 的排列 a,使 $\sum\limits_{i=2}^n \operatorname{dis}(a_{i-1},a_i)$ 最大,求这个最大值
$\operatorname{dis}(u,v)$表示从 u 到 v 的路径的中最短的边的边权,若有多条路径,则选令 $\operatorname{dis}(u,v)$最大的路径

输入描述:

1
第一行两个正整数 n,m接下来 m 行,每一行三个正整数 u,v,w 表示 u,v 之间有一条长度为 w 的边

输出描述:

表示最大的 $\sum\limits_{i=2}^n \operatorname{dis}(a_{i-1},a_i)$


题解

这个思路和最小生成树一模一样,就是求最大生成树而已。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#define Oo ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#include <bits/stdc++.h>
using namespace std;
#define PI acos(-1.0)
typedef long long ll;
struct node
{
ll x;
ll y;
ll w;
}a[500005];
ll cmp(node a , node b ){return a.w>b.w;}
ll f[500005];
ll _find(ll i)
{
if (i==f[i])return i;
else return f[i]=_find(f[i]);
}
int main()
{
Oo
ll n, m;
cin>> n >> m;
for (int i=0; i<m; i++)cin>>a[i].x>>a[i].y>>a[i].w;
for (int i=1; i<=n; i++)f[i]=i;
sort(a, a+m, cmp);
ll ans=0;
for (int i=0; i<m; i++)
{
int tx=_find(a[i].x);
int ty=_find(a[i].y);
if (tx!=ty)
{
f[tx]=ty;
ans+=a[i].w;
}
}
cout << ans << endl;
return 0;
}