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=bj−bk,想成图上的一条边
j
→
k
j→k
j→k,同时我们也会得到
k
→
j
k→j
k→j表示
−
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=1∑msi∗ai=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;
}