河南萌新联赛2024第(一)场:河南农业大学

 

造数

真的是白WA啊,如果他是0,那么就输出0。如果他是2或1,那么直接输出1。如果是跟一般的数,先让他去除二,如果他除二后是奇数,那么就减去1在除二,否则继续除二。一直计算到他是2或者1,结束。

#include<bits/stdc++.h>
using namespace std;
#define int  long long
#define endl '\n'
#define inf 0x3f3f3f3f3f3f3f3f
#define pii pair<int,int>

void solve(){
	int n;
	cin>>n;
	int sum=0;
	if(n==0){
		cout<<0<<endl;
		return;
	}
	if(n==2 or n==1){
		cout<<1<<endl;
		return;
	}
	while(1){
		if(n%2==1){
			n-=1;
			sum++;
		}
		n/=2;
		sum++;
		if(n%2==1){
			n-=1;
			sum++;
		}
		if(n==2 or n==1){
			sum++;
			break;
		}
	}
	cout<<sum<<endl;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);cout.tie(nullptr);
	int oyyo=1;
//	cin>>oyyo;
	
	while(oyyo--) {
		solve();
	}
	return 0;
}

图上计数(Easy)

眼力题,无算法的吓人题(有算法我也写不出)。

直接去分块就好了。因为可以任意删边, 所以最后的联通块可以任意组合 那么两个连通块数量最接近时最大

#include<bits/stdc++.h>
using namespace std;
#define int  long long
#define endl '\n'
#define inf 0x3f3f3f3f3f3f3f3f
#define pii pair<int,int>


void solve(){
	int n,m;
	cin>>n>>m;
	for (int i = 0; i < m; i++) {
		int u, v;
		cin >> u >> v;
	}
	int cnt = 0;
	if(n==1){
		cout<<0<<endl;
		return;
	}
	if(n%2==0){
		cout<<(n/2)*(n/2)<<endl;
		return;
	}else{
		cout<<(n/2)*(n/2+1)<<endl;
	}
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);cout.tie(nullptr);
	int oyyo=1;
//	cin>>oyyo;
	
	while(oyyo--) {
		solve();
	}
	return 0;
}

两难抉择

如果,数组的最大值是1,那么就让1去加上n这样乘出来会比只乘n大一,如果是另一个,那么取最大值,把他乘上n这个样就是最大值。

#include<bits/stdc++.h>
using namespace std;
#define int  long long
#define endl '\n'
#define inf 0x3f3f3f3f3f3f3f3f
#define pii pair<int,int>

void solve(){
	int n;
	cin>>n;
	vector<int>a(n);
	int max1=0,min1=inf;
	int sum=0;
	for(int i=0;i<n;i++){
		cin>>a[i];
		max1=max(max1,a[i]);
		min1=min(min1,a[i]);
		sum+=a[i];
	}
	if(max1!=1){
		sum-=max1;
		sum+=max1*n;
		cout<<sum<<endl;return;
	}else{
		sum+=n;
		cout<<sum<<endl;
		return;
	}
	
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);cout.tie(nullptr);
	int oyyo=1;
//	cin>>oyyo;
	
	while(oyyo--) {
		solve();
	}
	return 0;
}

 两难抉择新编

 级数内容1/n+2/n+3/n+4/n+.......=......

2e5算出的结果是1e6范围。所以可以暴力枚举。

#include<bits/stdc++.h>
using namespace std;
#define int  long long
#define endl '\n'
#define inf 0x3f3f3f3f3f3f3f3f
#define pii pair<int,int>

void solve(){
	int n;
	cin>>n;
	vector<int>a(n);
	int max1=-1,min1=inf;
	int k1=0,k2=0;
	int sum=0;
	for(int i=0;i<n;i++){
		cin>>a[i];
		sum^=a[i];
		if(a[i]>max1){
			max1=a[i];
			k1=i;
		}
		if(a[i]<min1){
			min1=a[i];
			k2=i;
		}
	}
	if(max1==1){
		sum^=1;
		sum^=(1+n);
		cout<<sum<<endl;
		return;
	}
	
	int max2=sum;
	
	for(int i=0;i<n;i++){
		for(int j=1;j<=n/(i+1);j++){
			int x=sum;
			x^=a[i];
			x^=(a[i]*j);
			max2=max(x,max2);
		}
	}
	cout<<max2<<endl;
	
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);cout.tie(nullptr);
	int oyyo=1;
//	cin>>oyyo;
	
	while(oyyo--) {
		solve();
	}
	return 0;
}

 除法移位

把最大的数移到最前面最大, 相同大小取操作次数少的。不要用double!!!!!!!!

#include<bits/stdc++.h>
using namespace std;
#define int  long long
#define endl '\n'
#define inf 0x3f3f3f3f3f3f3f3f
#define pii pair<int,int>


void solve(){
	int n,t;
	cin>>n>>t;
	vector<int >a(n);
	for(int i=0;i<n;i++){
		cin>>a[i];
	}
	int max1=a[0];
	int k=0;
	reverse(a.begin(),a.end());
	for(int i=0;i<min(n-1,t);i++){
		if(a[i]>max1){
			k=i+1;
			max1=a[i];
		}
	}
	cout<<k<<endl;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);cout.tie(nullptr);
	int oyyo=1;
//	cin>>oyyo;
	
	while(oyyo--) {
		solve();
	}
	return 0;
}

 旅途的终点

二分答案,我写了个题单,但还是没写出来。下面提供三个方法,这个的二分会爆long long,记得中途退出。换乘int128会无脑解。

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define inf 0x3f3f3f3f3f3f3f3f
#define pii pair<int,int>
const int mod=998244353;
int n,m,k;
int a[1000005];
int b[1000005];
bool check(int x){
	if(k>=x){
		return true;
	}
	memset(b,0,sizeof(b));
	for(int i=1;i<=x;i++){
		b[i]=a[i];
	}
	sort(b+1,b+x+1);
	int m1=m;
	for(int i=1;i<=x-k;i++){
		m1-=b[i];
		if(m1<=0) return 0;
	}
	return 1;
}

void solve(){
	cin>>n>>m>>k;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		b[i]=a[i];
	}
	if(k>=n){
		cout<<n<<endl;
		return;
	}
	int l=0,r=n;
	int ans=0;
	int mid;
	while(l<=r){
		mid=(l+r)>>1;
		if(check(mid)){
			ans=mid;
			l=mid+1;
		}else{
			r=mid-1;
		}
	}
	cout<<ans<<endl;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);cout.tie(nullptr);
	int oyyo=1;
	//cin>>oyyo;
	while(oyyo--) {
		solve();
	}
	return 0;
}

int128要用快读, 快写。

__int128的使用方法-CSDN博客

__int128的相关操作-CSDN博客

#include<bits/stdc++.h>
using namespace std;
#define int __int128
#define endl '\n'
#define inf 0x3f3f3f3f3f3f3f3f
#define pii pair<int,int>
const int mod=998244353;
int n,m,k;
int a[1000005];
int b[1000005];

inline void scan(__int128 &x){
	bool f=1;x=0;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-') f=!f;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	x=(f?x:-x);return;
}

void print(__int128 num)
{//递归调用,实现从高位向低位输出
	if(num>9) 
		print(num/10);
	putchar(num%10+'0');
}

bool check(int x){
	if(k>=x){
		return true;
	}
	memset(b,0,sizeof(b));
	for(int i=1;i<=x;i++){
		b[i]=a[i];
	}
	sort(b+1,b+x+1);
	int m1=m;
	for(int i=1;i<=x-k;i++){
		m1-=b[i];
	}
	if(m1>0){
		return true;
	}else{
		return false;
	}
}

void solve(){
	scan(n),scan(m),scan(k);
	for(int i=1;i<=n;i++){
		scan(a[i]);
		b[i]=a[i];
	}
	if(k>=n){
		print(n);
		return;
	}
	int l=0,r=n;
	int ans=0;
	int mid;
	while(l<=r){
		mid=(l+r)>>1;
		if(check(mid)){
			ans=mid;
			l=mid+1;
		}else{
			r=mid-1;
		}
	}
	print(ans);
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);cout.tie(nullptr);
	int oyyo=1;
	//cin>>oyyo;
	while(oyyo--) {
		solve();
	}
	return 0;
}

 优先队列做法。

#include<bits/stdc++.h>
using namespace std;
#define int  long long
#define endl '\n'
#define inf 0x3f3f3f3f3f3f3f3f
#define pii pair<int,int>



void solve(){
	int n,m,k;
	cin>>n>>m>>k;
	vector<int>a(n+1);
	vector<int>b(n+1);
	priority_queue<int,vector<int>,less<int>>q;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	int res=0;
	int z=0;
	for(int i=1;i<=n;i++){
		q.push(a[i]);
		res+=a[i];
		while(res>=m){
			int x=q.top();
			z++;
			res-=x;
			q.pop();
		}
		b[i]=z;
	}
	
	int l=0,r=n;
	int ans=0;
	while(l<=r){
		int mid=((r+l)>>1);
		if(b[mid]>k){
			r=mid-1;
		}else{
			ans=mid;
			l=mid+1;
		}
	}
	cout<<ans<<endl;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);cout.tie(nullptr);
	int oyyo=1;
//	cin>>oyyo;
	
	while(oyyo--) {
		solve();
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值