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;
}
相关推荐
YGGP3 分钟前
【每日八股】Redis篇(二):数据结构
数据结构·数据库·redis
web_1553427465629 分钟前
性能巅峰对决:Rust vs C++ —— 速度、安全与权衡的艺术
c++·算法·rust
计算机小白一个7 小时前
蓝桥杯 Java B 组之设计 LRU 缓存
java·算法·蓝桥杯
万事可爱^8 小时前
HDBSCAN:密度自适应的层次聚类算法解析与实践
算法·机器学习·数据挖掘·聚类·hdbscan
大数据追光猿10 小时前
Python应用算法之贪心算法理解和实践
大数据·开发语言·人工智能·python·深度学习·算法·贪心算法
Dream it possible!10 小时前
LeetCode 热题 100_在排序数组中查找元素的第一个和最后一个位置(65_34_中等_C++)(二分查找)(一次二分查找+挨个搜索;两次二分查找)
c++·算法·leetcode
夏末秋也凉10 小时前
力扣-回溯-46 全排列
数据结构·算法·leetcode
南宫生10 小时前
力扣每日一题【算法学习day.132】
java·学习·算法·leetcode
柠石榴10 小时前
【练习】【回溯No.1】力扣 77. 组合
c++·算法·leetcode·回溯
Leuanghing10 小时前
【Leetcode】11. 盛最多水的容器
python·算法·leetcode