康复训练第二场,已经不会做题了。$B$题写的姿势就不对,$C$题也没搞出来。
C
给出$ n $根长度不一的木棍,第 $i$ 根棍子长度为 $a_i$ 。两根长度分别为 $a_b$ 和 $a_c$ 的木棍可以拼接成一根长度为 $a_b+a_c$的木棍,同理 $3$ 根, $4$ 根,甚至 $n$ 根都能拼接。
问:使用这 $n$ 根木棍作三角形的边(一根木棍至多使用一次,也可以不使用),能拼出的面积最大的三角形的面积。
题解
由于数据很小,直接二进制枚举三边的棍子组成情况,然后判断情况是否合法,合法的情况用海伦公式求面积即可, 或者DFS暴力深搜。复杂度$O((1<<n)^3)$。
#include <bits/stdc++.h>
#define N 10
using namespace std;
typedef long long ll;
ll arr[N];int n;
ll cal(int tem) {
ll res = 0;
for (int i = 0; i < n; i++) {
if ((tem >> i) & 1)
res += arr[i];
}
return res;
}
bool Judge(ll a, ll b, ll c) {
if (a + b <= c || b + c <= a || a + c <= b)
return 1;
return 0;
}
int main() {
scanf("%d", &n);
double ans = -1;
for (int i = 0; i < n; i++) {
scanf("%lld", arr + i);
}
for (int i = 0; i < (1 << n); i++) {
ll A = cal(i);
for (int j = 0; j < (1 << n); j++) {
if (i & j)
continue;
ll B = cal(j);
for (int k = 0; k < (1 << n); k++) {
if (i & k || j & k) {
continue;
}
ll C = cal(k);
if (Judge(A, B, C))
continue;
double p = (A + B + C) / 2.0;
ans = max(ans, sqrt(p * (p - A) * (p - B) * (p - C)));
}
}
}
if (ans < 0)
printf("-1\n");
else
printf("%.1f\n", ans);
// system("pause");
return 0;
}
D
https://ac.nowcoder.com/acm/contest/11220/D
给出一个长度为 $n$ 的数组 $A$,下标从 $1$ 开始,$A_1,A_2,\cdots,A_n$。定义一个区间$\left[l,r \right]$是“有趣的区间”,当且仅当结$A_l|A_{l+1}|A_{l+2}|\cdots|A_{r-1}|A_{r}$果为奇数。
求“有趣的区间”的个数,两个区间$[L_1,R_1],[L_2,R_2]$相同,当且仅当$L_1=L_2$且$R_1=R_2$
题解
一个区间或运算后是否为奇数,根据或运算的性质,只需要判断这个区间的是否存在一个元素的二进制下的最低位是 $1$ ,如果存在,这个区间或运算后是奇数,反之为偶数。
本题求的是或运算后是奇数的区间,因此 “有趣的区间”$=$ “总区间个数” $−$ “无趣的区间”
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
int n;scanf("%d",&n);
ll sum=1ll*(n+1)*n/2;
ll cnt=0;
for(int i=0;i<n;i++){
int num;scanf("%d",&num);
if(num&1){
sum-=1ll*(cnt+1)*cnt/2;
cnt=0;
}else{
cnt++;
}
}
sum-=1ll*(cnt+1)*cnt/2;
printf("%lld\n",sum);
// system("pause");
return 0;
}
E
链接:https://ac.nowcoder.com/acm/contest/11220/E
有数字$1~9$,每个数字的个数分别为 $cnt_1,cnt_2,cnt_3,\cdots,cnt_9$。计算出“满意的集合“的个数。
"满意的集合" 定义:选出的数存在一种排列方式,其拼接起来后表示的十进制整数,能被$3$整除,例如集合 $\left\{3,3,6\right\}$(包含了 $2$个数字$3$,$1$个数字$6$ ),可以有排列$\left\{6,3,3\right\}$代表十进制下的整数 633,能被 3 整除。
两个集合相同,当且仅当集合元素个数相同,且排序后对应数字相同,例如$\left\{3,3,6\right\}$ 和 $\left\{3,6,3\right\}$ 是同样的集合. 空集合看作 0 ,是合法的,答案对$1e9+7$取模。
题解
#include <bits/stdc++.h>
#define ll long long
const int N=20,mod=1e9+7;
int cnt[N];
ll dp[N][3];
int main() {
for (int i=1; i<=9; i++) scanf("%d",&cnt[i]);
dp[0][0]=1;
for (int i=1; i<=9; i++) {
int mod1=1*i%3,mod2=2*i%3,mod3=3*i%3;
ll sum1=(cnt[i]+2)/3,sum2=(cnt[i]+1)/3,sum3=cnt[i]/3+1;
for (int MOD=0; MOD<3; MOD++) {
dp[i][(mod1+MOD)%3]+=sum1*dp[i-1][MOD];
dp[i][(mod2+MOD)%3]+=sum2*dp[i-1][MOD];
dp[i][(mod3+MOD)%3]+=sum3*dp[i-1][MOD];
dp[i][(mod1+MOD)%3]%=mod;
dp[i][(mod2+MOD)%3]%=mod;
dp[i][(mod3+MOD)%3]%=mod;
}
}
printf("%lld\n",dp[9][0]);
return 0;
}
0 条评论