Codeforces Global Round 15 A B D

这篇博客探讨了三道算法竞赛题目,包括字符串排序的最小子序列操作数、寻找最佳运动员的擂台赛策略以及数组差异化问题。通过实例解析了如何运用排序、双指针和图论思想解决问题,并强调了在解决竞赛题目的过程中,简洁有效的思路至关重要。
摘要由CSDN通过智能技术生成

C题因为过于的水就不写了…

A. Subsequence Permutation

题意:给你一个长度为n的字符串,确定一个最小数字k,将k个字符重新排列后字符串有序

idea:当时在网咖打的时候想复杂了,其实我们只要记录原字符串,记录排序后的字符串,遍历如果有一个字符不相等ans++,输出ans即可

#include<bits/stdc++.h>
#define LL long long
using namespace std;

int t,n;
int a[10101],b[10101];
char s[10100];
void solve()
{
	int ans = 0;
	scanf("%d",&n);
	scanf("%s",s);
	for(int i=1;i<=n;i++)
	{
		a[i] = b[i] = s[i-1]-'a';
	}
	sort( b+1,b+n+1 );
	for(int i=1;i<=n;i++)
	{
		if( a[i]!=b[i] )
		{
			ans++;
		}
	}
	printf("%d\n",ans);
}

int main()
{
	//freopen("in.txt","r",stdin);
	cin>>t;
	while( t-- ) solve();
	return 0;
}

B. Running for Gold

题意:给你 n n n个运动员,每个运动员有5场比赛排名,当x运动员至少有3场比赛比y运动员排名低时说明x运动员优于y运动员,请找出n个运动员中比其他运动员都优秀的运动员,如果不存在输出-1

idea:通过这题可以学到一个思想,一个词:“擂台赛”,如果一个人真的能获得金牌,那么他一定可以打败所有人,当然为了保险,我们第一次循环找到这个人,之后再进行一次循环,确认他是否能打败所有的人。

#include<bits/stdc++.h>
#define LL long long
#define N 100101
using namespace std;


int t,n,a[N][6];
bool check(int ans,int i)
{
	int cnt = 0;
	for(int j=1;j<=5;j++)
	{
		if( a[i][j]<a[ans][j] ) cnt++;
	}
	if( cnt>=3 ) return true;
	else return false;
}

void solve()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=5;j++)
		{
			scanf("%d",&a[i][j]);
		}
	}
	int ans = 1;
	for(int i=2;i<=n;i++)
	{
		if( check(ans,i) )
		{
			ans = i;
		}
	}
	for(int i=1;i<=n;i++)
	{
		if( i==ans ) continue;
		if( check(ans,i) )
		{
			printf("-1\n");
			return ;
		}
	}
	printf("%d\n",ans);
	return ;
}

int main()
{
//	freopen("in.txt","r",stdin);
	cin>>t;
	while( t-- )
	solve();	
	return 0;
}

D. Array Differentiation

题意:给定一个长度为n的a数组,问你能否构造出一个长度为n的数组b,满足b中存在两个数的差为a数组中的元素,且a数组中的元素必须都出现

idea:我们有n个数,前n-1个数很好办,n个数怎样都可以构造出来,问题就在这第n个数上。容易想到我们应该是要另外几个数凑起来得到n个数中某个数才可以。这种结构我们会想到一个环,n个点n条边。对于 a i = b j − b k a_i=b_j-b_k ai=bjbk,想成图上的一条边 j → k j→k jk,同时我们也会得到 k → j k→j kj表示 − a i -a_i ai,那么 n n n个点 n n n条边必然有一个环(注意不一定是全部点都在环上),假如这个环上有 m m m条边,把这个环上的边按顺序加起来,就会得到 ∑ i = 1 m s i ∗ a i = 0 \sum\limits_{i=1}^m s_i*a_i=0 i=1msiai=0,其中 s i ∈ { 1 , − 1 } s_i \in \{1,-1\} si{1,1} ,而对于环外的点我们一定能构造出合适的 b i b_i bi满足题意,类似下图:在这里插入图片描述
因此这是一个等价的命题,时间复杂度是 O ( 3 n ) O( 3^n ) O(3n)直接枚举 a i a_i ai选还是不选即可

#include<bits/stdc++.h>
#define LL long long
using namespace std;

int n,a[12];

bool dfs(int p,int h,int sum)
{
	if( sum==0 && h ) return true;
	if( p > n ) return false;
	if( dfs( p+1,h+1,sum + a[p] ) ) return true;
	if( dfs( p+1,h+1,sum - a[p] ) ) return true;
	if( dfs( p+1,h ,sum  ) ) return true;
	return false;
}

void solve()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	if( dfs( 1, 0, 0 ) ) printf("YES\n");
	else printf("NO\n");
}

int main()
{
	//freopen("in.txt","r",stdin);
	int t;
	cin>>t;
	while( t-- )
		solve();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值