《如 何 速 通 一 套 题》13.0

邮寄

开场秒掉 A。

B 不会做,写了 70。

----- 1h -----

然后看 C。

C 瞪了 114514 眼看不出来,然后再瞪了 1919810 眼,终于看出来了。

----- 3h -----

然后就不会了,D 啥都想不出来。

最后 100+70+100+0=270。

A 喷泉

弱智题。

直接计算 CAB 的距离 rA,BC 的距离最大值 +r 即可。

#include <bits/stdc++.h>
using namespace std;
using fl = double;
int t;
fl xa, ya, xb, yb, xc, yc, r;
fl len(fl x, fl y, fl x2, fl y2) {
return hypot(x2 - x, y2 - y);
}
int main() {
freopen("fountain.in", "r", stdin);
freopen("fountain.out", "w", stdout);
//ios::sync_with_stdio(0);
//cin.tie(0), cout.tie(0);
for(scanf("%d", &t); t--; ) {
//cin >> xa >> ya >> xb >> yb >> xc >> yc >> r;
scanf("%lf%lf%lf%lf%lf%lf%lf", &xa, &ya, &xb, &yb, &xc, &yc, &r);
//printf("%lf %lf %lf %lf %lf %lf %lf\n", xa, ya, xb, yb, xc, yc, r);
fl a = len(xa, ya, xc, yc), b = len(xb, yb, xc, yc), c = len(xa, ya, xb, yb);
fl x = (c + ((a + b) * (a - b) / c)) / 2;
printf("%.2lf %.2lf\n", sqrt(a * a - x * x) - r, max(a, b) + r);
//cout << fixed << setprecision(2) << sqrt(a * a - x * x) - r << ' ' << max(a, b) + r << '\n';
}
return 0;
}

B 红绿灯

把当前时间相同的合并在一起,维护每一个集合的当前时间,跳过啥都没做的循环,再加上数据随机,可以过。

#include <bits/stdc++.h>
using namespace std;
int n, m, arr[100010], f, fa[100010], ep[100010], cc, gd;
unordered_map<int, set<int> > mp;
int findfa(int x) {
return fa[x] == x? x : (fa[x] = findfa(fa[x]));
}
void unionn(int x, int y) {
x = findfa(x), y = findfa(y);
if(x == y) {
return ;
}
if(x < y) {
swap(x, y);
}
cc--;
fa[y] = x;
}
void cal(int x) {
if(gd % x == 0) {
return ;
}
for(int i = 1; i <= n; i++) {
i = findfa(i);
ep[i] = (ep[i] + x - 1) / x * x;
mp[ep[i]].insert(i);
}
for(auto &i : mp) {
for(auto j : i.second) {
unionn(j, *(i.second.begin()));
}
}
gd = 0;
for(int i = 1; i <= n; i++) {
i = findfa(i);
gd = __gcd(gd, ep[i]);
}
mp.clear();
}
int main() {
freopen("light.in", "r", stdin);
freopen("light.out", "w", stdout);
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n >> m;
//scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i++) {
cin >> arr[i];
//scanf("%d", arr + i);
f |= arr[i] > 3;
}
gd = 1;
m = unique(arr + 1, arr + m + 1) - arr - 1;
if(f || m <= 10 || n * m <= 1000000) {
iota(fa + 1, fa + n + 1, 1);
iota(ep + 1, ep + n + 1, 1);
cc = n;
for(int i = 1; i <= m; i++) {
cal(arr[i]);
//cout << i << ' ' << cc << '\n';
}
for(int i = 1; i <= n; i++) {
cout << ep[findfa(i)] << ' ';
//printf("%d ", ep[findfa(i)]);
}
cout << '\n';
//printf("\n");
}else {
for(int i = 1; i <= n; i++) {
cout << (i + 5) / 6 * 6 << ' ';
//printf("%d ", (i + 5) / 6 * 6);
}
cout << '\n';
//printf("\n");
}
return 0;
}

C 子集

首先我们假设选了 x 个元素,易知答案为 knx

所以我们设 dpx 为子集和为 x 时的答案,每一次加入一个数时维护 dp 就可以了。

dp0=kn

加一个数时:

dpi+axdpik

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int kMod = int(1e9) + 7;
int t, n, m, k, arr[5050], dp[5050], ik;
int qpow(int x, int y) {
int rs = 1;
for(; y; y >>= 1) {
if(y & 1) {
rs = 1ll * rs * x % kMod;
}
x = 1ll * x * x % kMod;
}
return rs;
}
int qinv(int x) {
return qpow(x, kMod - 2);
}
int main() {
freopen("subset.in", "r", stdin);
freopen("subset.out", "w", stdout);
for(cin >> t; t--;) {
cin >> n >> m >> k;
ik = qinv(k);
dp[0] = qpow(k, n);
for(int i = 1; i <= n; i++) {
cin >> arr[i];
for(int j = m - arr[i]; j >= 0; j--) {
dp[j + arr[i]] = (dp[j + arr[i]] + 1ll * dp[j] * ik) % kMod;
}
}
cout << dp[m] << '\n';
fill(dp, dp + m + 1, 0);
}
return 0;
}
posted @   hhc0001  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
点击右上角即可分享
微信分享提示