专栏文章

AC源Day4模拟赛复盘

个人记录参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mioj3tc9
此快照首次捕获于
2025/12/02 20:02
3 个月前
此快照最后确认于
2025/12/02 20:02
3 个月前
查看原文

单击此处添加标题

T1(100 AC)

排序后乘法原理解决
CPP
#include<bits/stdc++.h>
#define int long long
#define N 25
using namespace std;

int n,ans=1;
int a[N],b[N],f[N];
int find(int l,int r,int x){	
	int mid=(l+r)/2;
	if((a[mid]>x && a[mid-1]<x) || a[mid]==x) return mid;
	else if(a[mid]<x && a[mid+1]>x) return mid+1;
	else if(x>a[mid]) return find(mid+1,r,x);
	else return find(l,mid,x);
}

signed main(){
	
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	freopen("apple.in","r",stdin);
	freopen("apple.out","w",stdout);
	
	cin>>n;
	for(int i=1;i<=n;i++) cin>>b[i];
	for(int i=1;i<=n;i++) cin>>a[i];
	sort(a+1,a+n+1);
	sort(b+1,b+n+1);
	if(b[1]>a[1] || b[n]>a[n]){
		cout<<0;
		return 0;
	}
	for(int i=1;i<=n;i++){
		f[i]=n-find(1,n,b[i])+1;
	}
	for(int i=n;i>=1;i--){
		ans*=f[i]-(n-i);
	}
	cout<<ans;
	return 0;
}

T2(100 AC)

观察得知只要有相同种类的奶茶间隔不超过一个就可以统一成哪一种,简单扫一遍搞定。
CPP
#include<bits/stdc++.h>
#define int long long
#define N 200005
using namespace std;

int n,t;
int last[N],a[N];

signed main(){
	
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	freopen("tea.in","r",stdin);
	freopen("tea.out","w",stdout);
	
	cin>>t;
	for(int i=1;i<=t;i++){
		memset(last,0,sizeof(last));
		memset(a,0,sizeof(a));
		map<int,bool> mp;
		cin>>n;
		for(int i=1;i<=n;i++){
			int x;
			cin>>x;
			if(last[x] && i-last[x]<=2) mp[x]=1;
			last[x]=i;
		}
		bool hv=0;
		for(auto i:mp){
			if(i.second) hv=1,cout<<i.first<<" ";
		}
		if(!hv) cout<<-1<<"\n";
		else cout<<"\n";
	}
	return 0;
}

T3(100 AC)

对于一个数字xx,其答案为max(t[x],sum)max(t[x],sum)(sum是其前面数量为0的数的个数,t数组为其自身的个数)。
CPP
#include<bits/stdc++.h>
#define int long long
#define N 200005
using namespace std;

int n,a[N];
map<int,int> mp;

signed main(){
	
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	freopen("mex.in","r",stdin);
	freopen("mex.out","w",stdout);
	
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		mp[a[i]]++;
	}
	int ans=0;
	for(int x=0;x<=n;x++){
		if(x>0) if(mp[x-1]==0) ans++;
		cout<<max(mp[x],ans)<<"\n";
	}
	return 0;
}

T4(10 TLE)

对数组正序倒序各跑一遍单调栈找到上一个更大的元素。
下:O(n3)O(n^3)暴力代码(10分)
CPP
#include<bits/stdc++.h>
#define int long long
#define N 300005
using namespace std;

int n;
int h[N],rx[N];

signed main(){
	
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	freopen("frisbee.in","r",stdin);
	freopen("frisbee.out","w",stdout);
	
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>h[i];
	}
	int ans=0;
	for(int i=1;i<=n;i++){
		for(int j=i+1;j<=n;j++){
			bool ps=1;
			for(int k=i+1;k<=j-1;k++){
				if(h[k]>min(h[i],h[j])){
					ps=0;
					break;
				}
			}
			if(ps){
				ans+=j-i+1;
			}
		}
	}
	cout<<ans;
	return 0;
}
满分代码↓
CPP
#include<bits/stdc++.h>
#define int long long
#define N 300005
using namespace std;

int n;
int h[N],ans=0;
stack<int> s;

signed main(){
	
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>h[i];
	}
	for(int i=1;i<=n;i++){
		while(!s.empty() && h[s.top()]<h[i]) s.pop();
		if(!s.empty()) ans+=i-s.top()+1;
		s.push(i);
	}
	while(!s.empty()) s.pop();
	for(int i=n;i>=1;i--){
		while(!s.empty() && h[s.top()]<h[i]) s.pop();
		if(!s.empty()) ans+=s.top()-i+1;
		s.push(i);
	}
	
	cout<<ans;
	return 0;
}

T5(15 WA)

离线+并查集,易知对于每个连通块包含点的个数nnans=n×(n+1)2ans=\sum \frac{n \times (n+1)}{2},采用离线加点思想,将Si=1Si=1的点涂黑并size=0,标志其不在时也可通过。
  • 遇到 si = 1 的节点, 将黑色节点所属的并查集 size+1。并更新ans。
  • 遇到 si = 0 的节点,(将其染成黑色), 将与 si = 0 相邻的黑色节点合并起来,更新答案。
代码涵待更新......

T6(0 WA)

贪心+结论优化。可以确定是先加后乘更赚。只加一次,因为再加都不如翻倍之前的。
代码涵待更新......

评论

0 条评论,欢迎与作者交流。

正在加载评论...