Codeforces Round #740 (Div. 2, based on VK Cup 2021 - Final (Engine))

本文介绍了两个编程竞赛题目,一个是关于序列排序的问题,通过模拟操作找到使序列有序的最少次数;另一个涉及怪物战斗策略,求解最小初始力量值以击败所有怪物。文章分析了两种问题的解决方法,包括直接模拟和二分查找,并反思了在实现过程中的错误和优化思路。
摘要由CSDN通过智能技术生成

https://codeforces.com/contest/1561/problem/A

定义一个操作,对数列的1-n,交换num[i]和num[i+1],为f(i)为奇数时只对奇数交换,为f(i)为偶数时只对偶数交换,问你至少需要多少次操作使得数列有序。

由于数据非常的小,我们可以直接枚举f(i),直接模拟,然后对每次模拟检测一遍数列是否有序就可以了。

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=n;i>=a;i--) 
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
inline ll read()
{	
	ll x=0,w=1; char ch=0;ch=getchar();
	while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
	while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+(ch-48);ch=getchar();}
	return x*w;
}
inline void print(ll x)
{
	if(x<0){x=-x;putchar('-');}
	if(x>9)print(x/10);
	putchar(x%10+48);
}	
const int N=1000;
int t,n,num[N];	
int check()
{
	//rep(i,1,n)cout<<num[i]<<endl;
	for(int i=1;i<=n-1;i++)
	{
		if(num[i]>num[i+1])return 1;
	}
	return 0;
}
void solve()
{
	memset(num,0,sizeof(num));
	int k=0; n=0;
	cin>>n;
	rep(i,1,n)cin>>num[i];
	while(check())
	{
		//cout<<1<<endl;
		k++;
		if(k%2)
		{
			for(int i=1;i<=n;i++)
			{
				if(i%2&&i!=n)
				{
					if(num[i]>num[i+1])swap(num[i],num[i+1]);
				}
			}
		}
		else
		{
			for(int i=1;i<=n;i++)
			{
				if(i%2==0)
				{
					if(num[i]>num[i+1])swap(num[i],num[i+1]);
				}
			}
		}
	}
	cout<<k<<endl;
	//rep(i,1,n)cout<<num[i]<<' ';cout<<endl;
}
int main()
{
	ios
	cin>>t;
	while(t--)solve();
	return 0;
}

https://codeforces.com/contest/1561/problem/C

有n个洞穴,在洞穴里有m只怪物,每只怪物有一个护甲值,如果你力量值高于护甲值你就能击杀这个怪物,每击杀一个怪物会增加一点力量值,怪物需要按顺序杀,但是你可以选择进入洞穴的顺序,问你你能够击杀所有的怪物的前提下,开始的最小力量值是多少。

我的思路是对每个洞穴最小需要的力量值进行二分答案,找到能够击败这个洞穴所有怪物的最小力量,然后对每个洞穴的力量值进行排序,再二分一次答案,找到大于等于能够击败所有洞穴怪物的力量。

复杂度nlogn+nlogn

其实并不需要这么麻烦,遇到力量值不够的情况直接把力量值提高到刚好能击败怪物就可以了。写的麻烦了码力不够,最后太困了搞错了排序之后洞穴的大小和击败这个洞穴需要的最小力量就不匹配了。还是太菜了。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#define ll long long
#define ull unsigned long long
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=n;i>=a;i--) 
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
inline ll read()
{	
	ll x=0,w=1; char ch=0;ch=getchar();
	while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
	while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+(ch-48);ch=getchar();}
	return x*w;
}
inline void print(ll x)
{
	if(x<0){x=-x;putchar('-');}
	if(x>9)print(x/10);
	putchar(x%10+48);
}		
bool cmp(pair<int,int> a,pair<int,int> b)
{
	return a.second<b.second;
}
const int N=1e5+5;
int t,n,s;
pair<int,int> power[N];
vector<int> cave[N];
int tmp;
int check(int a,int x)
{
	for(int i=0;i<cave[x].size();i++)//写成cave[i].size..粗心啊 
	{
		if(a>cave[x][i])a++;
		else return 0;
		//cout<<a<<'---';
	}
	return 1;
}
int checks(int a)
{
	for(int i=1;i<=n;i++)
	{
		if(a > power[i].second)//排序之后cave【i】和power【i】就对不上了.. 
		{
			a+=power[i].first;
			//cout<<'a'<<a<<endl;
		}
		else return 1;
	}
	return 0;
}
void solve()
{
	cin>>n;
	rep(i,1,n)
	{
		cave[i].clear();
	}
	rep(i,1,n)
	{
		cin>>s;
		rep(j,1,s)
		{
			cin>>tmp;
			cave[i].push_back(tmp);
		}
		//一定要按顺序打,这里不能排序。debug 
		int l=1,r=1e9+5,ans=0;
		while(l<=r)
		{
			int mid=(l+r)/2;
			if(check(mid,i))
			{
				ans=mid;
				r=mid-1;
			}
			else l=mid+1;
			//cout<<mid<<' '<<ans<<endl;
		}
		power[i].first=cave[i].size();
		power[i].second=ans;
	}
//	rep(i,1,n)
//		{
//			rep(j,0,cave[i].size()-1)
//			{
//				cout<<cave[i][j]<<' ';
//			}
//			cout<<endl;
//		}
	
	sort(power+1,power+n+1,cmp);//我power是从1开始的,不能从0开始排。debug1小时。 
	//rep(i,1,n)cout<<power[i]<<' ';cout<<endl;
	int l=1,r=1e9+5,ans=0;
	while(l<=r)
	{
		int mid=(l+r)/2;
		if(checks(mid))
		{
			ans=mid;
			l=mid+1;
		}
		else r=mid-1;
	}
	cout<<ans<<endl;
}
int main()//本想对每个洞穴里面的怪排序 
{
	ios
	cin>>t;
	while(t--)solve();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值