THIRD PROGRAMMING CONTEST 2023 ALGO(AtCoder Beginner Contest 318)

THIRD PROGRAMMING CONTEST 2023 ALGO(AtCoder Beginner Contest 318)

A - Full Moon

思路:模拟

直接模拟即可,找到以m开始每一次可以调p的距离终点为n的次数

c++ 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,m,q;cin>>n>>m>>q;
    int res=1;
    while(n>m){
        m+=q;
        res++;
    }
    if(n<m)res--;
    cout<<res;
}

B - Overlapping sheets

思路:暴力

由于矩阵不是很大,之间标记每一组能覆盖的点即可

c++ 复制代码
#include<bits/stdc++.h>
using namespace std;
int a[110][110];
int main(){
    int n;
    int res=0;
    cin>>n;
    while(n--){
        int x,y,x1,y1;
        cin>>x>>y>>x1>>y1;
        for(int i=x;i<=y-1;i++){
            for(int j=x1;j<=y1-1;j++)a[i][j]++;
        }
    }
    
    for(int i=0;i<=100;i++){
        for(int j=0;j<=100;j++)if(a[i][j]>0)res++;
    }
    cout<<res;
}

C - Blue Spring

思路:贪心+排序

我们先排个序,然后计算d天花费和特价票的价格的大小,如果特价更优惠就跟新需要花费的钱

c++ 复制代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e6+7;
int a[N],s[N];
signed main(){
    int n,d,p;
    cin>>n>>d>>p;
    int sum=0;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        sum+=a[i];
    }
    sort(a+1,a+1+n);
    for(int i=1;i<=n;i++){
        s[i]=s[i-1]+a[i];
    }
    int id=n;
    while(id){
        if(id-d<0)d=id;
        int m=s[id]-s[id-d];
        //cout<<m<<endl;
        if(m>p){
            sum-=(m-p);
            id=id-d;
        }else break;
    }
   // cout<<id<<endl;
    cout<<sum;
}

D - General Weighted Max Matching

思路:dfs

一眼看过去这是一般图的最大权独立集,根本没啥多项式做法。

所以就直接爆搜的就好了,也就是对于每一个点找它匹配的点,需要注意的是可以有点不匹配边。

这样的复杂度就是 O(N!!)O(N!!) 显然可以过。

c++ 复制代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 20;
int n,match[N],d[N][N],ans,sum;
void dfs(int now){
	if(now == n + 1){
		ans = max(ans,sum);
		return;
	}
	if(match[now]){
		dfs(now+1);
		return;
	}
	for(int i=now+1; i<=n; i++){
		if(match[i])	continue;
		match[now] = i,match[i] = now;
		sum += d[now][i];
		dfs(now+1);
		match[now] = match[i] = 0;
		sum -= d[now][i];
	}
	dfs(now+1);
}
signed main(){
	scanf("%lld",&n);
	for(int i=1; i<=n; i++){
		for(int j=i+1; j<=n; j++){
			scanf("%lld",&d[i][j]);
		}
	}
	dfs(1);
	printf("%lld\n",ans);
	return 0;
}

E - Sandwiches

思路:前后缀数组

由于数有105,我们只能枚举其中一个。要么枚举 i要么枚举 j。分别考虑后发现枚举 j简单一点。

如果枚举下标i会发现比较难计算,对于当前的 ai,那么对于之后的每个 ak都要考虑它们之间的其他数的个数,感觉复杂度会比较大。

考虑枚举下标j,剩下的就是考虑 j左边和 j右边的相同数。这个j对答案的贡献就是 ∑x≠ajlx×rx,其中 lx表示 j左边 x(是值,不是下标)的个数, rx就是右边的 x的个数。

考虑当 j移动时,只有 aj和 aj+1这两个数的个数发生变化。因此我们事先维护 ∑的值,∑−laj×raj就是此时的 j对答案的贡献。转移时通过加减那两个数的贡献,就得到 j移动到下一个数时的 ∑的值。然后累计就是答案了

c++ 复制代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;cin>>n;
    vector<int>a(n+10,0);
    vector<int>l(n+10,0),r(n+10,0);
    for(int i=0;i<n;i++){
        int x;
        cin>>x;
        a[i]=x;
        r[a[i]]++;
    }
    int ans=0;
    int res=0;
    for(int i=0;i<n;i++){
        res-=1ll*(l[a[i]]*r[a[i]]);
        ans+=res;
        r[a[i]]--;
        l[a[i]]++;
        res+=1ll*(l[a[i]]*r[a[i]]);
    }
    cout<<ans;
}
相关推荐
努力写代码的熊大16 分钟前
单链表和双向链表
数据结构·链表
军训猫猫头22 分钟前
1.如何对多个控件进行高效的绑定 C#例子 WPF例子
开发语言·算法·c#·.net
success36 分钟前
【爆刷力扣-数组】二分查找 及 衍生题型
算法
Orlando cron1 小时前
数据结构入门:链表
数据结构·算法·链表
牛客企业服务2 小时前
2025年AI面试推荐榜单,数字化招聘转型优选
人工智能·python·算法·面试·职场和发展·金融·求职招聘
糖葫芦君3 小时前
Policy Gradient【强化学习的数学原理】
算法
向阳@向远方4 小时前
第二章 简单程序设计
开发语言·c++·算法
github_czy5 小时前
RRF (Reciprocal Rank Fusion) 排序算法详解
算法·排序算法
许愿与你永世安宁6 小时前
力扣343 整数拆分
数据结构·算法·leetcode
爱coding的橙子6 小时前
每日算法刷题Day42 7.5:leetcode前缀和3道题,用时2h
算法·leetcode·职场和发展