目录
A. Subsequence Permutation
题意:
给你一个字符串,问你要把这个字符串中的字符按从小到大排列,至少需要改变几个字符的位置。
思路:
将字符串进行排序,然后将原来的字符串和排序后的字符串逐字符比对,若不一样,则说明该字符的位置发生了变化。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
char a[1000];
char b[1000]
;
int main()
{
int q;
cin>>q;
while(q--)
{
int n;
cin>>n;
scanf("%s",a+1);
for(int i = 1; i <= n; i++)
{
b[i] = a[i];
}
sort(a,a+n+1);
int ans = 0;
for(int i = 1; i <= n; i++)
{
if(a[i] != b[i])ans++;
}
cout<<ans<<endl;
}
}
B. Running for Gold
传送门
题意:
给出n个人参加的五场比赛的名次,规定一个人的某三项比赛名次大于另一个人的对应的这三项比赛的名次,则说明前者比后者优秀,现在问你是否能找到最优秀的人,若能,则输出这个人的序号。
思路:
从第一个人到最后一个人,用当前最优秀的人进行比对,最终得出一个可能是最优秀的人的人选,然后再让这个人去比较其它所有人,如果没有人比他更优秀,那么这个人就是答案,否则没有最优秀的人。
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<map>
#include<queue>
#include<math.h>
#include<set>
using namespace std;
#define ll long long
struct node{
int a,b,c,d,e;
int i;
}e[500010];
int main()
{
int t;
cin>>t;
while(t--)
{
int aa = 0x3f3f3f3f,bb = 0x3f3f3f3f,cc = 0x3f3f3f3f,dd = 0x3f3f3f3f,ee = 0x3f3f3f3f;
int f = 0;
int n;
cin>>n;
for(int i = 1; i <= n; i++)
{
cin>>e[i].a>>e[i].b>>e[i].c>>e[i].d>>e[i].e;
}
for(int i = 1; i <= n; i++)
{
int cnt = 0;
if(e[i].a <= aa)cnt++;;
if(e[i].b <= bb)cnt++;
if(e[i].c <= cc)cnt++;
if(e[i].d <= dd)cnt++;
if(e[i].e <= ee)cnt++;
if(cnt >= 3)
{
aa = e[i].a;
bb = e[i].b;
cc = e[i].c;
dd = e[i].d;
ee = e[i].e;
f = i;
}
}
for(int i = 1; i <= n; i++)
{
int cnt = 0;
if(aa <= e[i].a)cnt++;
if(bb <= e[i].b)cnt++;
if(cc <= e[i].c)cnt++;
if(dd <= e[i].d)cnt++;
if(ee <= e[i].e)cnt++;
if(cnt >= 3)continue;
else
{
f = 0;
break;
}
}
if(f)
{
cout<<f<<endl;
}
else
cout<<"-1"<<endl;
}
}
C. Maximize the Intersections
传送门
题意:
一个圆上有2*n个点,现在让其中部分点两两相连,问你当所有点都连接上其它点后,它们的交点的最大值是多少。
思路:
这是一个我没有得出证明的结论:对于事先已经连好的点,我们可以无视它的影响,将其它未连接的点按次序排列,并分为相等数量的两组,然后两组对应位置的点相连接(即第一组的第一个点连上第二组的第一个点,依次下去…),最后再计算交点数量即可。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int pot[210];
int vis[210];
int node[210];
int main()
{
int t;
cin>>t;
while(t--)
{
memset(pot,0,sizeof(pot));
memset(node,0,sizeof(node));
memset(vis,0,sizeof(vis));
int n,k;
cin>>n>>k;
for(int i = 1; i <= k; i++)
{
int x,y;
cin>>x>>y;
pot[x] = y;
pot[y] = x;
vis[x] = vis[y] = 1;
}
int cnt = 0;
for(int i = 1; i <= 2*n; i++)
{
if(!vis[i])
{
vis[i] = 1;
node[++cnt] = i;
}
}
for(int i = 1; i <= cnt/2; i++)
{
pot[node[i]] = node[cnt/2+i];
pot[node[cnt/2+i]] = node[i];
}
int ans = 0;
for(int i = 1; i <= 2*n; i++)
{
for(int j = i+1; j <= pot[i]; j++)
{
if(pot[j] > pot[i] )ans++;
}
}
cout<<ans<<endl;
}
}
D. Array Differentiation
传送门
题意:
给你一个长度为n的数列a,求长度为n的数列b,满足ai = bj - bk。
思路:
枚举所有的a[i]的组合的和,若出现任意长度的组合的和等于a[i]的值,那么b存在。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int a[110];
int n;
int flag;
void dfs(int sum,int i)
{
if(i > n)return;
if(sum+a[i] == 0 || sum - a[i] == 0)flag = 1;
if(flag == 1)return;
dfs(sum+a[i],i+1);
dfs(sum,i+1);
dfs(sum-a[i],i+1);
}
int main()
{
int t;
cin>>t;
while(t--)
{
flag = 0;
cin>>n;
for(int i = 1; i <= n; i++)
{
cin>>a[i];
}
if(n == 1 && a[1] == 0)
{
cout<<"YES"<<endl;
continue;
}
else if(n== 1 && a[1] != 0)
{
cout<<"NO"<<endl;
continue;
}
dfs(0,1);
if(flag)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}