2024ccpc全国邀请赛(郑州)暨第六届ccpc河南省赛(ABFHJM)

题目链接:Dashboard - 2024 National Invitational of CCPC (Zhengzhou), 2024 CCPC Henan Provincial Collegiate Programming Contest - Codeforces

这是我大一第一次参加CCPC,只拿到了一个省铜······

还需继续努力in---

补题环节:

Problem A. Once In My Life

题目描述:给定两个数n和d,找到一个正整数k,使得二者的乘积n·k是幸运数。

解题思路:幸运数包含1到9,所以我们可以构造一个数N为1234567890+d,那么N就一定是幸运数,这时我们只需要把N作为n的前缀,然后减去(N作为n的前缀的数%n),那么N就一定可以整除n,最后输出这个数/n即可。

实现代码:

#include<bits/stdc++.h>
#define int long long 
#define endl "\n"
#define fi first
#define se second
#define PII pair<int,int> 
using namespace std;
const int N=1e6+5;
int a[N];
const int M=1234567890;
void solve(){
	int n,d;
	cin >> n >> d;
	int m=M+d;
	int len=to_string(n).size();
	m=m*pow(10,len);
	m+=n;
	m-=m%n;
	cout << m/n << endl;
	return ;
}
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int t=1;
	cin >> t;
	while(t--) solve();
	return 0;
}

Problem B. 扫雷 1

题意描述:进行n轮游戏,每轮获得一个金币,同时每轮也可以无限次购买地雷探测器,给出地雷探测器的价格,问最多可以买多少个探测器。

解题思路:贪心策略+双指针:先给每轮的地雷探测器进行升序排序并且统计这些价格的数量,每轮游戏找最便宜的地雷探测器,若不满足减去这个数量,满足则全买这个地雷探测器,同时也减去这个数量,当最便宜的地雷探测器的数量为0时,指针向右移动,最后输出答案即可。

实现代码:

#include<bits/stdc++.h>
#define int long long 
#define endl "\n"
#define fi first
#define se second
#define PII pair<int,int> 
using namespace std;
const int N=2e5+5;
int a[N],b[N];
map<int,int> m;
void solve(){
	int n;
	cin >> n;
	for(int i=0;i<n;++i){
		cin >> a[i];
		b[i]=a[i];
		m[a[i]]++;
	}
	sort(b,b+n);
	int p=0,ans=0,cnt=0;
	for(int i=0;i<n;++i){
		cnt++;
		if(a[i]==b[p]){
			ans+=cnt/a[i];
			cnt%=a[i];
		}
		m[a[i]]--;
		if(i==n-1) break;//当i指针循环到最后时,直接break,否则下面的while语句会无限执行
		while(m[b[p]]==0) p++;
	}
	cout << ans;
	return ;
}
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int t=1;
	//cin >> t;
	while(t--) solve();
	return 0;
}

Problem F. 优秀字符串

题意描述:一个优秀的字符串满足以下条件:

• S 的长度|S|恰好为5;

• S 的第三个字符与第五个字符相同

• S 的前四个字符互不相同。

求优秀字符串的数量。

解题思路:签到题,直接暴力模拟就行。

实现代码:

#include<bits/stdc++.h>
#define int long long 
#define endl "\n"
#define fi first
#define se second
#define PII pair<int,int> 
using namespace std;
const int N=1e6+5;
//int a[N];
int ans=0; 
void solve(){	
	string s;
	cin >> s;
	map<char,int> v;
	if(s.size()!=5) return;
	if(s[2]!=s[4]) return;
    for(int i=0;i<s.size()-1;++i){
    	if(v[s[i]]) return ;
    	v[s[i]]++;
	}
	ans++;
	return ;
}
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int t=1;
	cin >> t;
	while(t--) solve();
	cout << ans;
	return 0;
}

Problem H. 随机栈

题目描述:有2n次操作,每次操作有两种情况:

-1:从集合里面取出一个数

非-1:将这个数存入集合里面

求最后取出来的数组满足递增(小于等于后一项)的概率,然后对这个概率进行取模处理。

解题思路:首先我们可以开一个最小堆模拟集合,因为每次取出的数必须是集合里面最小的数,否则就不满足题意,堆中的元素总数分母,当前队头的最小元素的数量即为分子,该数量可以用map来记录,计算不同分数的积并进行取模,最后将分母进行快速幂的逆元,然后乘上分子在取模一次即可。

实现代码:

#include<bits/stdc++.h>
#define int long long 
#define endl "\n"
#define fi first
#define se second
#define PII pair<int,int> 
using namespace std;
const int N=2e5+5;
int a[N];
int cnt[N];
priority_queue<int,vector<int>,greater<int>> q;
const int mod=998244353;
int quick_mi(int a,int b){
	int ans=1;
	while(b){
		while(b%2==0) a=a*a%mod,b/=2;
		ans=ans*a%mod,b-=1;
	}
	return ans;
}
void solve(){
	int n;
	cin >> n;
	int fz=1,fm=1;
	int maxn=0;
	for(int i=1;i<=n*2;++i){
		int x;
		cin >> x;
		if(x!=-1){
			q.push(x),cnt[x]++;
			if(x<maxn){
				cout << 0 << endl;
				return ;
			}
		}
		else{
			fz=(fz*cnt[q.top()])%mod;
			fm=(fm*q.size())%mod;
			maxn=max(maxn,q.top());
			cnt[q.top()]--,q.pop();
		}
	}
	fm=quick_mi(fm,mod-2)%mod;
	int ans=(fz*fm)%mod;
	cout << ans << endl;
	return ;
}
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int t=1;
	//cin >> t;
	while(t--) solve();
	return 0;
}

Problem J. 排列与合数

题目描述:给出一个五位数字,重排后在没有前导零的情况下是否可能出现合数;

解题思路:当这个数含偶数必然是合数,而当这个数全为奇数时由样例可知也一定为合数,所以不可能出现不为合数的情况(不需要考虑-1),那么暴力判断(先考虑含0的情况)即可。

实现代码:

#include<bits/stdc++.h>
#define int long long 
#define endl "\n"
#define fi first
#define se second
#define PII pair<int,int> 
using namespace std;
const int N=2e5+5;
int a[N],b[N];
map<int,int> m;
void solve(){
	char ch1,ch2,ch3,ch4,ch5;
	cin >> ch1 >> ch2 >> ch3 >> ch4 >> ch5;
	if(ch1=='0'){
		cout << ch2 << ch3 << ch4 << ch5 << ch1<< endl;
		return ;
	}
	if(ch2=='0'){
		cout << ch1 << ch3 << ch4 << ch5 << ch2<< endl;
		return ;
	}
	if(ch3=='0'){
		cout << ch2 << ch1 << ch4 << ch5 << ch3<< endl;
		return ;
	}
	if(ch4=='0'){
		cout << ch2 << ch3 << ch1 << ch5 << ch4<< endl;
		return ;
	}
	if(ch5=='0'){
		cout << ch2 << ch3 << ch4 << ch1 << ch5<< endl;
		return ;
	}
	if((ch1-'0')%2==0){
		cout << ch2 << ch3 << ch4 << ch5 << ch1<< endl;
		return ;
	}
	if((ch2-'0')%2==0){
		cout << ch1 << ch3 << ch4 << ch5 << ch2<< endl;
		return ;
	}
	if((ch3-'0')%2==0){
		cout << ch2 << ch1 << ch4 << ch5 << ch3<< endl;
		return ;
	}
	if((ch4-'0')%2==0){
		cout << ch2 << ch3 << ch1 << ch5 << ch4<< endl;
		return ;
	}
	if((ch5-'0')%2==0){
		cout << ch2 << ch3 << ch4 << ch1 << ch5<< endl;
		return ;
	}
	else cout << "97531" << endl;
	return ;
}
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int t=1;
	cin >> t;
	while(t--) solve();
	return 0;
}

M. 有效算法

题意描述:给出长度为n的数组a,b,对每个ai进行以下操作:

将ai 变成满足|ai−x|≤k×bi 的任意整数x。

求满足操作下的最小的非负整数k。

解题思路:对k进行二分即可,依照题目的操作,我们可以得到下列两个式子:

ai​≥x:  ai​−k×bi​≤x<=ai

ai<=x:  ai<=x<=k×bi​+ai

因此可以求出x的区间,最后套用二分求左边界的模板即可。

实现代码:

#include<bits/stdc++.h>
#define int long long 
#define endl "\n"
#define fi first
#define se second
#define PII pair<int,int> 
using namespace std;
const int N=1e6+5;
vector<int> a,b;
int n;
int check(int k){
	int minn=1e9+5,maxn=0;
	for(int i=1;i<=n;++i){
		minn=min(minn,a[i]+k*b[i]);
		maxn=max(maxn,a[i]-k*b[i]);
		if(maxn>minn) return 0;
	}
	return 1;
}
void solve(){	
	cin >> n;
	a.resize(n+1),b.resize(n+1);
	for(int i=1;i<=n;++i) cin >> a[i];
	for(int i=1;i<=n;++i) cin >> b[i];
	int l=0,r=1e9;
	while(l<r){
		int mid=l+r>>1;
		if(check(mid)) r=mid;
		else l=mid+1;
	}
	cout << l << endl;
	return ;
}
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int t=1;
	cin >> t;
	while(t--) solve();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值