The 2019 ACM-ICPC China Shannxi Provincial Programming Contest
C:
题意差不多就是求点到圆的切线的切点。
#include <bits/stdc++.h>
using namespace std;
const double PI= atan((double)1)*4;
int main() {
int T;
scanf("%d", &T);
while(T--) {
double rx, ry, x, y, r;
scanf("%lf%lf%lf%lf%lf", &rx, &ry, &r, &x, &y);
double ans = 0;
if(x-rx<0) x=x+2*(rx-x);
if(x-rx>r) {
ans = PI*0.5*r+sqrt((y-ry)*(y-ry)+(x-rx-r)*(x-rx-r));
} else {
double dd = (x-rx)*(x-rx)+(y-ry)*(y-ry);
double d = sqrt(dd);
double dr = r*r;
double l = sqrt(dd-dr);
double j = asin(r/d);
// cout << j << endl;
double x0=(rx-x);
double y0=(ry-y);
// cout << ry << " " << y0 << endl;
double x1 = x0*cos(j)-y0*sin(j);
double y1 = x0*sin(j)+y0*cos(j);
x1=x1/d*l+x;
y1=y1/d*l+y;
// cout << x1 << " " << y1 << endl;
ans+=sqrt((x1-x)*(x1-x)+(y1-y)*(y1-y));
// cout << ans << " " << atan((y1-ry)/(x1-rx)) << endl;
ans+=(0.5*PI+atan((y1-ry)/(x1-rx)))*r;
}
printf("%.4f\n", ans);
}
}
D:
题意是给N个将军和M个将军的冲突关系。要求冲突的将军不能在同一边。题目保证有解,那么就说明没有奇环。因此由冲突关系组成的图中有两类子图:(1)单个点,这种情况就视为一个物品。(2)有偶环的图,随便从一点开始dfs可以处理出互斥的两组将军,将其分别求和,得出两个互斥的物品。
然后使用背包进行求解。互斥的物品由于必须拿其中的一个,因此将大的物品权值减去小的物品权值,看成一个物品。之后用bitset进行背包问题求解即可。
#include <bits/stdc++.h>
using namespace std;
const int N = 207;
const int B = 5e6+7;
int c[N];
bool vis[N];
vector<int> adj[N];
int sm[2];
void dfs(int u, int p) {
vis[u]=true;
sm[p]+=c[u];
for(int v : adj[u]) {
if(vis[v]) continue;
dfs(v, p^1);
}
}
vector<int> a;
int main() {
int T;
scanf("%d", &T);
while(T--) {
int n, m;
scanf("%d%d", &n, &m);
memset(vis,