2019牛客暑期多校训练营(第一场)[ABCEF]

本文提供了多种算法题目的解决方案,包括Equivalence Prefixes问题中寻找等效前缀的方法,Integration问题中利用乘法逆元计算特定表达式的技巧,Euclidean Distance问题通过拉格朗日乘数法求解欧几里得距离,以及DP问题E-ABBA中的动态规划策略等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题虫洞——A:A Equivalent Prefixes

参考博客:2019牛客多校第一场

(备注:队友A的,我后来才看的,,哭唧唧, 下面附上队友的AC代码)

#include<bits/stdc++.h>
using namespace std;
 
const int maxn = 1e5 + 10;
int n,cnt;
int a[maxn],b[maxn];
 
int main()
{
    while(~scanf("%d",&n))
    {
        for(int i = 0;i < n; ++i) scanf("%d",&a[i]);
        for(int i = 0;i < n; ++i) scanf("%d",&b[i]);
        cnt = n - 1;
        for(int i = 0;i <= cnt; ++i)
        {
            for(int j = i + 1;j <= cnt; ++j)
            {
                int f = 0;
                if(a[i] > a[j]) f++;
                if(b[i] > b[j]) f++;
                if(f == 2) break;
                if(f == 1)
                {
                    cnt = j - 1;
                    break;
                }
            }
        }
        printf("%d\n",cnt + 1);
    }
    return 0;
}


问题虫洞—— B:B Integration

问题分析:

在这里插入图片描述(此处还需用乘法逆元)

//#include<bits/stdc++.h>
#include  <stdio.h>
#include <iostream>
#include<algorithm>
//#include      <map>
//#include      <set>
//#include   <vector>
//#include    <queue>
//#include    <stack>
#include <stdlib.h>
#include  <cstring>
#include <string.h>
#include   <string>
#include   <math.h>
using namespace std;
typedef long long ll;
#define MAXN 10005
#define INF 0x3f3f3f3f//将近ll类型最大数的一半,而且乘2不会爆ll
const int mod = 1000000007;

ll inv(ll b){return b == 1? 1: (mod-mod/b)*inv(mod%b)%mod;}//递推乘法逆元
ll a[MAXN];
int main()
{
    int n;
    while(cin >> n){
        for(int i=0; i<n; ++i)
            scanf("%lld", &a[i]);
        ll sum=0;
        for(int i=0; i<n; ++i){
            ll ans=1;
            for(int j=0; j<n; ++j){
                if(j != i)
                    ans = (ans*(a[j]*a[j]%mod - a[i]*a[i]%mod+mod)%mod)%mod;
            }
            ans = ans*2*a[i]%mod;
            ans = inv(ans);
            sum=(ans+sum)%mod;
        }
        cout << sum << '\n';
    }
	return 0;
}


问题虫洞——C:C Euclidean Distance

问题分析:(拉格朗日乘数法)

在这里插入图片描述

//#include<bits/stdc++.h>
#include  <stdio.h>
#include <iostream>
#include<algorithm>
//#include      <map>
//#include      <set>
//#include   <vector>
//#include    <queue>
//#include    <stack>
#include <stdlib.h>
#include  <cstring>
#include <string.h>
#include   <string>
#include   <math.h>
using namespace std;
typedef long long ll;
#define MAXN 10005
#define INF 0x3f3f3f3f//将近ll类型最大数的一半,而且乘2不会爆ll
const ll mod = 1000000007;
#define mem(a, b) memset(a, b, sizeof(a))

ll a[MAXN];         //原数组
ll sum[MAXN];       //前缀和
ll gcd(ll a, ll b){
    return b?gcd(b, a%b):a;
}

int main()
{
    int n, m;
    while(cin >> n >> m){
       for(int i=1; i<=n; ++i)
        scanf("%lld", &a[i]);
       sort(a+1, a+n+1, greater<ll>());//大->小
       for(int i=1; i<=n; ++i)
        sum[i] = sum[i-1]+a[i];          //前缀和
        ll x, y; // x为分子, y为分母
        int flag = n;////标记最终推到哪个位置,如果都行肯定是推到最后的位置
        for(int i=0; i<=n; ++i){
            if(sum[i] - a[i+1]*i > m){//最多推到i
                //sum[i]-a[i+1]*i表示前i个位置推到a[i+1]需要的m值
                flag = i;
                break;
            }
        }
         //推完后前flag的值为 (sum[flag]-m)/flag;
         x = (sum[flag] - m)*(sum[flag] - m)*flag;//flag个
         y = flag*flag;
         for(int i=flag+1; i<=n; ++i)
            x+=a[i]*a[i]*y;                         //*y是通分
         y*=m*m;
         ll g = gcd(x, y);
         if(g == y) cout << x/g << '\n';
         else cout <<  x/g << '/' << y/g << '\n';

    }
    return 0;
}


问题虫洞——E(dp):E ABBA


参考博客:2019牛客暑期多校训练营(第一场)E-ABBA

附上比较好的理解:

令f[i][j]为有i个A,j个B的合法方案数

当有i - j < n时,说明还没有凑齐n个AB,要满足有n个AB,A在前面的数量还不够,所以后面可以放A
f[i + 1][j] = f[i][j] + f[i + 1][j];

当有j - i < m时,说明还没有凑齐m个BA,要满足有m个BA,B在前面的数量还不够,所以后面可以放B
f[i][j + 1] = f[i][j] + f[i][j + 1];

//#include<bits/stdc++.h>
#include  <stdio.h>
#include <iostream>
#include<algorithm>
//#include      <map>
//#include      <set>
//#include   <vector>
//#include    <queue>
//#include    <stack>
#include <stdlib.h>
#include  <cstring>
#include <string.h>
#include   <string>
#include   <math.h>
using namespace std;
typedef long long ll;
#define MAXN 1005
#define INF 0x3f3f3f3f//将近ll类型最大数的一半,而且乘2不会爆ll
const ll mod = 1000000007;
#define mem(a, b) memset(a, b, sizeof(a))

int dp[MAXN*2][MAXN*2];
int main()
{
    int n, m;
    while(~scanf("%d %d", &n, &m)){
       for (int i = 0; i <= n + m; i++)			//此处不能用memset置0;
            for (int j = 0; j <= n + m; j++)
                dp[i][j] = 0;
        dp[0][0] = 1;
        for(int i=0; i<=n+m; ++i){
            for(int j=0; j<=n+m; ++j){
                if(j >= i+1-n)
                    dp[i+1][j] = (dp[i+1][j]+dp[i][j])%mod;
                if(i >= j+1-m)
                    dp[i][j+1] = (dp[i][j+1] + dp[i][j])%mod;
            }
        }
        cout << dp[n+m][n+m] << '\n';
    }
    return 0;
}


问题虫洞——F:F Random Point in Triangle

问题分析:11/2倍的三角形ABC面积

(咱也不知道,咱也不敢问,咱就是在莽)

不错的博客:2019牛客多校第一场 F-Random Point in Triangle

#include<bits/stdc++.h>
using namespace std;
 
typedef long long ll;
ll a1,b1,a2,b2,a3,b3;
 
int main()
{
    while(~scanf("%lld%lld%lld%lld%lld%lld",&a1,&b1,&a2,&b2,&a3,&b3))
    {
        ll ans = a1 * b2 + a3 * b1 + a2 * b3 - a3 * b2 - a2 * b1 - a1 * b3;
        printf("%lld\n",abs(ans * 11));
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值