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;
}
相关推荐
budingxiaomoli5 小时前
算法--滑动窗口(一)
数据结构·算法
王哈哈^_^6 小时前
【数据集】【YOLO】【目标检测】农作物病害数据集 11498 张,病害检测,YOLOv8农作物病虫害识别系统实战训推教程。
人工智能·深度学习·算法·yolo·目标检测·计算机视觉·1024程序员节
xier_ran6 小时前
邻接矩阵的 k 次幂意味着什么?从图论到路径计数的直观解释
算法·图论
B站_计算机毕业设计之家6 小时前
预测算法:股票数据分析预测系统 股票预测 股价预测 Arima预测算法(时间序列预测算法) Flask 框架 大数据(源码)✅
python·算法·机器学习·数据分析·flask·股票·预测
想唱rap7 小时前
C++ list 类的使用
c语言·开发语言·数据结构·c++·笔记·算法·list
l1t8 小时前
利用DuckDB SQL求解集合数学题
数据库·sql·算法·集合·duckdb
yuyanjingtao8 小时前
CCF-GESP 等级考试 2024年9月认证C++四级真题解析
c++·算法·青少年编程·gesp·csp-j/s
微笑尅乐8 小时前
洗牌算法讲解——力扣384.打乱数组
算法·leetcode·职场和发展
Lei_3359678 小时前
[算法]背包DP(01背包、完全背包问题、多重背包、分组背包、混合背包问题、有依赖的背包问题等)
c++·算法
uesowys8 小时前
华为OD算法开发指导-比赛的冠亚季军
算法·华为od