hdu5948 hdu5949 hdu5950 hdu5952 hdu5954
A Thickest Burger
对于每对 A B, 输出 m a x ( 2 A + B , 2 B + A ) max(2A + B, 2B + A) max(2A+B,2B+A)
B Relative atomic mass
给出一个字符串,只包含CHO,原子质量分别是12,1,16,求出这个字符串总的质量即可
C Recursive sequence
矩阵快速幂,式子是 a [ i ] = 2 a [ i − 2 ] + a [ i − 1 ] + i 4 a[i] = 2a[i - 2] + a[i - 1] + i^4 a[i]=2a[i−2]+a[i−1]+i4,关键在于根据这个式子推导出转移矩阵,然后直接 l o g n logn logn 实现即可
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 2147493647;
struct matrix{
int a[8][8];
matrix(){
memset(a, 0, sizeof a);
}
};
matrix mul(const matrix& x, const matrix& y){
matrix ans;
for(int i = 0; i < 7; ++i){
for(int j = 0; j < 7; ++j){
for(int k = 0; k < 7; ++k){
ans.a[i][j] += x.a[i][k] * y.a[k][j];
ans.a[i][j] %= mod;
}
}
}
return ans;
}
matrix qpow(matrix a, int b){
matrix ans;
memcpy(ans.a, a.a, sizeof a.a);
if(b == 0) return ans;
b--;
while(b){
if(b & 1LL) ans = mul(ans, a);
a = mul(a, a);
b >>= 1LL;
}
return ans;
}
signed main(){
matrix A, B;
A.a[0][2] = 16;
A.a[0][3] = 8;
A.a[0][4] = 4;
A.a[0][5] = 2;
A.a[0][6] = 1;
B.a[0][0] = B.a[0][1] = 1;
B.a[1][0] = 2;
B.a[2][0] = B.a[2][2] = 1;
B.a[3][0] = B.a[3][2] = 4;
B.a[3][3] = 1;
B.a[4][0] = B.a[4][2] = 6;
B.a[4][3] = 3;
B.a[4][4] = 1;
B.a[5][0] = B.a[5][2] = 4;
B.a[5][3] = 3;
B.a[5][4] = 2;
B.a[5][5] = 1;
for(int i = 0; i < 7; ++i)
B.a[6][i] = 1;
B.a[6][1] = 0;
int t;
cin >> t;
while(t--){
int n, a, b;
cin >> n >> a >> b;
matrix C = A, D = B;
C.a[0][1] = a;
C.a[0][0] = b;
if(n == 1){
cout << a << endl;
continue;
}
else if(n == 2){
cout << b << endl;
continue;
}
n -= 2;
D = qpow(D, n);
C = mul(C, D);
cout << C.a[0][0] << endl;
}
return 0;
}
D Couting Cliques
给出一个无向图,有n个顶点和m条边,求顶点刚好为S的完全子图。
这里因为n只有100,m只有1000,S不超过10,所以直接爆搜,然后剪枝即可(一开始的时候还在苦苦想着有没有更好的想法,大意了)
#include<bits/stdc++.h>
using namespace std;
const int N = 111;
const int M = 1111;
int e[M], ne[M], h[N], idx;
void add(int a, int b){
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
}
int vis[N];
int mp[N][N];
int n, m, s;
int ans;
int a[11];
int at;
inline int read() {
int X = 0; bool flag = 1; char ch = getchar();
while (ch < '0' || ch>'9') { if (ch == '-') flag = 0; ch = getchar(); }
while (ch >= '0' && ch <= '9') { X = (X << 1) + (X << 3) + ch - '0'; ch = getchar(); }
if (flag) return X;
return ~(X - 1);
}
void dfs(int now){
if(at == s){
ans++;
return;
}
for(int i = h[now]; i != -1; i = ne[i]){
int y = e[i];
int flag = 1;
if(y < now) continue;
for(int j = 0; j < at; ++j){
int z = a[j];
if(mp[y][z] == 0){
flag = 0;
break;
}
}
if(flag){
a[at++] = y;
dfs(y);
at--;
}
}
}
signed main(){
int t;
t = read();
while(t--){
memset(mp, 0, sizeof mp);
memset(h, -1, sizeof h);
idx = 0;
ans = 0;
at = 0;
n = read(), m = read(), s = read();
for(int i = 0; i < m; ++i){
int u, v;
u = read(), v = read();
add(u, v);
mp[u][v] = mp[v][u] = 1;
}
for(int i = 1; i <= n - s + 1; ++i){
a[at++] = i;
dfs(i);
at--;
}
printf("%d\n", ans);
}
return 0;
}
E Do not pour out
当d >= 1 时,上面是一个完整的椭圆,用简单的推算直接求出椭圆的 a a a 和 b b b,椭圆面积公式 π a b \pi ab πab 即可。
关键是当 d < 1时,椭圆面是会被截去一部分的,如图
设
m
i
d
,
t
,
y
mid, t, y
mid,t,y,根据相似三角形得到
t
m
i
d
=
2
−
y
2
\frac{t}{mid} = \frac{2 - y}{2}
midt=22−y,所以有
t
=
(
2
−
y
)
m
i
d
2
t = \frac{(2 - y)mid}{2}
t=2(2−y)mid
有效底面积是
θ
+
(
t
−
1
)
s
i
n
(
θ
)
\theta + (t - 1)sin(\theta)
θ+(t−1)sin(θ),其中
θ
=
a
r
c
c
o
s
(
1
−
t
)
\theta = arccos(1 - t)
θ=arccos(1−t),这里不需要特判
t
t
t 和 1 的大小关系,神奇的三角函数已经帮我们考虑这种关系了。
所以总结一下公式
①
t
=
(
2
−
y
)
m
i
d
2
②
θ
=
a
r
c
c
o
s
(
1
−
t
)
③
S
(
t
)
=
θ
+
(
t
−
1
)
s
i
n
(
θ
)
④
V
=
∫
0
2
S
(
t
(
y
)
)
d
y
① \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ t = \frac{(2 - y)mid}{2}\\② \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \theta = arccos(1 - t)\\③ \ \ \ \ S(t) = \theta + (t - 1)sin(\theta)\\④ \ \ \ \ \ \ \ \ \ \ \ \ \ \ V = \int_{0}^{2}S(t(y))dy
① t=2(2−y)mid② θ=arccos(1−t)③ S(t)=θ+(t−1)sin(θ)④ V=∫02S(t(y))dy
然后就是代换,③代入④得到
⑤
V
=
∫
0
2
(
θ
+
(
t
−
1
)
s
i
n
θ
)
d
y
⑤\ \ \ \ \ \ \ V = \int_{0}^{2}(\theta + (t - 1)sin\theta)dy
⑤ V=∫02(θ+(t−1)sinθ)dy
由①得
y
=
2
−
2
t
m
i
d
y = 2 - \frac{2t}{mid}
y=2−mid2t,所以得到
⑥
d
y
=
−
2
m
i
d
s
i
n
θ
d
θ
⑥\ \ \ \ \ \ dy = -\frac{2}{mid}sin\theta \ d\theta
⑥ dy=−mid2sinθ dθ
由②
⑦
t
=
1
−
c
o
s
θ
⑦\ \ \ \ \ t = 1 - cos\theta
⑦ t=1−cosθ
⑦代入⑤得到
⑧
V
=
∫
0
2
(
θ
−
s
i
n
θ
c
o
n
θ
)
d
y
⑧\ \ \ \ \ \ \ \ V =\int_{0}^{2}(\theta - sin\theta con\theta)dy
⑧ V=∫02(θ−sinθconθ)dy
⑥代入⑧ 得到
⑨
V
=
−
2
m
i
d
∫
a
b
(
(
θ
−
s
i
n
θ
c
o
s
θ
)
s
i
n
θ
)
d
θ
⑨\ \ \ \ \ \ \ \ \ V = -\frac{2}{mid}\int_{a}^{b}((\theta - sin\theta cos\theta)sin\theta)d\theta
⑨ V=−mid2∫ab((θ−sinθcosθ)sinθ)dθ
得到的⑨式中的积分区间是发生了变化的,从原来的对
y
y
y 积分变成了对
θ
\theta
θ 积分,这里根据 公式⑥进行新区间范围计算
[
a
r
c
c
o
s
(
1
−
m
i
d
)
,
a
r
c
c
o
s
(
1
)
]
[arccos(1 - mid), arccos(1)]
[arccos(1−mid),arccos(1)],所以最后的积分公式为
⑩
V
=
−
2
m
i
d
∫
a
r
c
c
o
s
(
1
−
m
i
d
)
a
r
c
c
o
s
(
1
)
(
θ
s
i
n
θ
−
s
i
n
2
θ
c
o
s
θ
)
d
θ
⑩\ \ \ \ \ \ \ \ \ V = -\frac{2}{mid}\int_{arccos(1 - mid)}^{arccos(1)}(\theta sin\theta - sin^2\theta cos\theta)d\theta
⑩ V=−mid2∫arccos(1−mid)arccos(1)(θsinθ−sin2θcosθ)dθ
然后就是求积分了,的到最后需要实现的计算公式
V
=
−
2
m
i
d
[
s
i
n
(
x
)
−
x
c
o
s
(
x
)
−
1
3
s
i
n
3
(
x
)
]
a
c
o
s
(
a
−
m
i
d
)
a
c
o
s
(
1
)
V = -\frac{2}{mid}[sin(x) - x cos(x) - \frac{1}{3}sin^3(x)]_{acos(a - mid)}^{acos(1)}
V=−mid2[sin(x)−xcos(x)−31sin3(x)]acos(a−mid)acos(1)
这样就可以通过二分求
m
i
d
mid
mid,得到
m
i
d
mid
mid 之后,可以求出斜面和底面的夹角
α
\alpha
α,根据图形得到以下关系
c
o
s
α
=
m
i
d
2
2
+
m
i
d
2
=
S
底
S
0
cos \alpha = \frac{mid}{\sqrt{2^2 + mid^2}} = \frac{S_底}{S_0}
cosα=22+mid2mid=S0S底
这里
S
0
S_0
S0 表示斜面面积,
S
底
S_底
S底 表示
S
0
S_0
S0 在底面的投影,
S
底
S_底
S底 可以用②③公式求出来,所以答案就是
S
0
=
S
底
2
2
+
m
i
d
2
m
i
d
S_0 = \frac{S_底 \sqrt{2^2 + mid^2}}{mid}
S0=midS底22+mid2
#include<bits/stdc++.h>
using namespace std;
const double PI = acos(-1.0);
const double eps = 1e-10;
double f(double x){
return sin(x) - x * cos(x) - pow(sin(x), 3) / 3;
}
double getV(double mid){
double a = acos(1 - mid);
double b = acos(1);
return -2.0 / mid * (f(b) - f(a));
}
double getS(double t){
double theta = acos(1 - t);
return theta + (t - 1) * sin(theta);
}
int main(){
int t;
cin >> t;
while(t--){
double d;
cin >> d;
if(fabs(d) < eps){
printf("%.5f\n", 0);
continue;
}
if(d < 1){
double l = 0, r = 2;
while(fabs(r - l) > eps){
double mid = (l + r) / 2;
if(getV(mid) < PI * d)
l = mid;
else r = mid;
}
double mid = (l + r) / 2;
double S = getS(mid);
double S1 = S * sqrt(4 + mid * mid) / mid;
printf("%.5f\n", S1);
}
else{
double a = sqrt(1 + (2 - d) * (2 - d));
double b = 1;
double S = PI * a * b;
printf("%.5f\n", S);
}
}
return 0;
}