0
点赞
收藏
分享

微信扫一扫

牛客月赛补题报告

Mezereon 2022-01-15 阅读 48

木棍游戏:

题意:给你n个木棍,然后让你组成一个面积最大的三角形。

需要用到的知识点:DFS,and 海伦公式(求三角形的面积)

需要注意的点就是:“可以不用这个木棍。”

可以给A加,也可以给B加,C同样如此。

ac代码:

#include <iostream>
#include <math.h>
using namespace std;
int n;
int A=0,B=0,C=0;
double ans=-1;
int a[20];
void dfs(int u)
{
if(u>n){
if(A + B > C C > B C > A);
else return;
double p = (A+B+C)/2;
double s = sqrt(p*(p-A)*(p-B)*(p-C));
if(s>ans) ans = s;
return;
}
dfs(u+1);
A+=a[u];
dfs(u+1);
A-=a[u];B+=a[u];
dfs(u+1);
B-=a[u];C+=a[u];
dfs(u+1);
C-=a[u];
}

int main() {
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
dfs(1);
printf("%.1f",ans);
return 0;
}

有趣的区间:

way1:直接前缀和➕二分求解:

注意题意:“有一个奇数就可以了,枚举左边界,如果是奇数,那么所有边界任选,如果是偶数,从右边找第一个奇数就可以了。”

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <math.h>
typedef long long ll;
using namespace std;
const int maxn = 1e6+10;
const int INF = 0x3f3f3f3f;
//int fac[maxn];
int arr[maxn];
int presum[maxn];
int main() {
int n;
ll ans=0;
scanf("%d",
for(int i=1;i<=n;i++){
ll a;
scanf("%d",
if(arr[i]%2!=0) presum[i]=presum[i-1]+1;
else presum[i] = presum[i-1];
}
for(int i=1;i<=n;i++){
//这里是奇数,所以后面都可以
if(arr[i]%2) ans+=n-i+1;
else{
//这里是偶数,所以需要二分找到后面的第一个奇数
int idx = lower_bound(presum+1, presum+1+n, presum[i]+1) - presum;
if(idx <= n) ans += n - idx + 1;
}
}
printf("%lld\n",ans);
return 0;
}

way2:

先算出区间的所有可能,然后减去偶数区间的:

#include <iostream>
#include <math.h>
using namespace std;
const int maxn = 1e6+10;

int arr[maxn];

int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++){
int a;
cin>>a;
if(a%2!=0){
arr[i]=1;
}else{
arr[i]=0;
}
}
long long lens = (long long)n*(n+1)/2;
long long len;
int pre=1;
for(int i=1;i<=n;i++){
if(arr[i]%2!=0){
len = i - pre;
lens -= (long long)(len+1)*len/2;
pre = i + 1;
}
}
len = n +1 - pre;//这个地方不是奇数,不能够直接用n
lens -= (long long)(len+1)*len/2;
printf("%lld\n",lens);
return 0;
// pre = i + 1;

}

满意的集合:

这一道题的整体思路就是直接对每种情况进行枚举,dfs。

但是由于数据量过大,所以不作枚举。

要判一个数是否是3得倍数==>只需要把每一位加起来看是不是3的倍数对吧==>也就是说,有x个i,对这个数的数位和的贡献就是x*i==>然后我们把x*i%3等价==>也就是说,只要求出对于i,有多少个x会使得x*i%3=0、1、2就行==>如果i是0,那么x取任何值都使得x*i%3=0(如果i是1,那么x取1、4、7会使得x*i%3=1)

举个例子,

5个1

没有1时,是贡献是0

1个1,贡献是1,

2个1,贡献是2

3个1,贡献是0

4个1,贡献是1

5个1,贡献是2

所以对0的贡献是2,对1的贡献是2,对2的贡献是2

#include <iostream>
typedef long long ll;
using namespace std;
const int mod = 1e9+7;
ll arr[22][22];
ll ans=0;

void dfs(int x,int y,int tmp){
if(x==10){
if( y % 3 ==0 ) ans = (ans + tmp) % mod;
return;
}
for(int i=0;i<=2;i++){
dfs(x+1,y+i,tmp*arr[x][i]%mod);
}
}

int main() {
int n;
int rem;
for(int i=1;i<=9;i++){
int a;
scanf("%d",
rem = i % 3;
if(rem==0) arr[i][0]=a+1;
if(rem==1){
arr[i][0] = a / 3 + 1 ;
arr[i][1] = (a+2) / 3 ;
arr[i][2] = (a+1) / 3 ;
}
if(rem==2){
arr[i][0] = a / 3 + 1 ;
arr[i][1] = (a+1) / 3 ;
arr[i][2] = (a+2) / 3 ;
}
}
dfs(1,0,1);
printf("%lld",ans);
return 0;
//首先进行预处理为0,1,2的个数,然后再dfs进行处理
}
举报

相关推荐

0 条评论