2022牛客多校第一场ACDGIJ
Posted 灀龗䯦縷
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2022牛客多校第一场ACDGIJ相关的知识,希望对你有一定的参考价值。
A- Villages: Landlines
题意:
在一条横轴上给定 n n n个点横坐标 x s x_s xs和半径 r s r_s rs,可以在横轴上任意两点连线,问连接这 n n n个点形成的圆的连线最小长度为多少。
1 ≤ n ≤ 2 ∗ 1 0 5 , − 1 0 9 ≤ x s ≤ 1 0 9 , 1 ≤ r s ≤ 1 0 9 1\\le n\\le 2*10^5,-10^9 \\leq x_s \\leq 10^9, 1\\leq r_s\\leq 10^9 1≤n≤2∗105,−109≤xs≤109,1≤rs≤109
思路:
等价于给了 n n n个区间起点和终点,排序贪心即可。时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)
代码:
cin >> n;
for (int i = 1; i <= n; i++)
int a, b;
cin >> a >> b;
w[i] = a - b, a + b;
sort(w + 1, w + 1 + n);
int ans = 0;
int now = w[1].y;
for (int i = 2; i <= n; i++)
if (w[i].x > now)
ans += w[i].x - now;
now = max(now, w[i].y);
cout << ans << endl;
C- Grab the Seat!
题意:
给定 n ∗ m n*m n∗m的二维平面,有 k k k个坐标点已有人。 q q q次询问,每次将第 p i p_i pi个坐标点的人换到 ( x i , y i ) (x_i,y_i) (xi,yi),问二维平面中好位置的数量,修改永久成立。
好位置的定义:对于一个位置 ( x i , y i ) (x_i,y_i) (xi,yi)满足与 ( 0 , 1 ) (0,1) (0,1)和 ( 0 , m ) (0,m) (0,m)的直线相交区间内没有人。
思路:
以 ( 0 , 1 ) (0,1) (0,1)为例,从 ( 0 , 1 ) (0,1) (0,1)往所有有人的坐标点发出射线,对于同一 y i y_i yi, x i x_i xi越小斜率越大,显然斜率越大的遮盖的面积越大,因此对于每一行维护到当前为止的最大斜率,根据直线公式算出向上取整的 x x x。 ( 0 , m ) (0,m) (0,m)做法类似,两者 x x x取 m i n min min,则 x − 1 x-1 x−1为当前列合法的位置数。复杂度 O ( m q ) O(mq) O(mq)
代码:
#include <bits/stdc++.h>
#define int long long
#define x first
#define y second
#define endl '\\n'
using namespace std;
const int N = 200010, M = 2 * N, _ = 0, P = 13331;
typedef pair<int, int> pii;
int k, t, q, n, m;
pii w[N];
int pos[N];//当前y x最小的位置
int ans[N];//合法位置数量
void work()
for (int i = 1; i <= m; i++)
pos[i] = n + 1;
for (int i = 1; i <= k; i++)
auto [x, y] = w[i];
pos[y] = min(pos[y], x);
int dx = 1, dy = 0;
// y=(dy/dx)x+1 x=(y-1)*dx/dy
for (int i = 1; i <= m; i++)
if (i == 1)
ans[i] = pos[i] - 1;
else
int x = pos[i], y = i;
if ((y - 1) * dx >= x * dy)
dx = x, dy = y - 1;
ans[i] = ((i - 1) * dx + dy - 1) / dy - 1; //向上取整
dx = 1, dy = m;
// y=(dy/dx)x+m x=(y-m)*dx/dy
for (int i = m; i >= 1; i--)
if (i == m)
ans[i] = min(ans[i], pos[i] - 1);
else
int x = pos[i], y = i;
if ((y - m) * dx <= x * dy)
dx = x, dy = y - m;
ans[i] = min(ans[i], ((i - m) * dx + dy + 1) / dy - 1); //向上取整,dy是负数因此dy+1
int res = 0;
for (int i = 1; i <= m; i++)
res += ans[i];
cout << res << endl;
void solve()
cin >> n >> m >> k >> q;
for (int i = 1; i <= k; i++)
int a, b;
cin >> a >> b;
w[i] = a, b;
while (q--)
int a, b, c;
cin >> a >> b >> c;
w[a] = b, c;
work();
signed main()
ios::sync_with_stdio(false), cin.tie(nullptr);
int T;
// cin >> T;
T = 1;
while (T--)
solve();
return (0 ^ _ ^ 0);
D- Mocha and Railgun
猜结论过的。复杂度 O ( 1 ) O(1) O(1)。
代码:
double r, x, y, d;
cin >> r >> x >> y >> d;
double oa = sqrt(x * x + y * y);
double oe = oa - d;
double boe = acos(oe / r);
double of = oa + d;
double cof = acos(of / r);
double jj = fabs(boe - cof);
cout << fixed << setprecision(12) << jj * r << endl;
G- Lexicographical Maximum
题意:
求 1 ∼ n 1\\sim n 1∼n中字典序最大的数。 1 ≤ n ≤ 1 0 1000000 1\\le n\\le 10^1000000 1≤n≤101000000
思路:
令 n n n长度为 l e n len len,若 s t r [ 1 ∼ l e n − 1 ] str[1\\sim len-1] str[1∼len−1]全是 9 9 9,则 n n n即为最大数;否则 l e n − 1 len-1 len−1个 9 9 9为最大数。复杂度 O ( n ) O(n) O(n)。
代码:
cin >> str + 1;
n = strlen(str + 1);
int f=1;
for(int i=1;i<n;i++)
if(str[i]!='9')
f=0;
break;
if(f)for(int i=1;i<=n;i++)cout<<str[i];
else for(int i=1;i<n;i++)cout<<9;
cout<<endl;
H- Fly
待补。无限期鸽。
I- Chiitoitsu
题意:
给定 13 13 13张初始手牌,初始手牌不会出现超过两张相同的牌。问在最优策略下单人麻将自动摸切最终以七对子自摸胡牌的期望回合数是多少。
思路:
一回合中摸牌只有两种情况:需要/不需要。
考虑概率 d p dp dp。假设当前手上还有 r e s res res张牌没凑成对子,牌河里还有 n o w now now张牌。若摸到的牌是需要的,概率为 r e s ∗ 3 n o w \\fracres*3now nowres∗3,没凑成对子的数量少一张,并且打出一张没凑成对子的牌,总计 r e s − = 2 res-=2 res−=2,牌河少一张以上是关于2022牛客多校第一场ACDGIJ的主要内容,如果未能解决你的问题,请参考以下文章