Deltix Round, Summer 2021 codeforce
题目链接
Take Your Places!
题目意思和分析
给定一串数字,我们可以进行一个操作,就是交换两个相邻的数字,最后我们要保证奇数和偶数不能够相邻,求的是最少的操作次数。
基本思路就是直接按照奇数或者偶数的相对位置来进行交换,比如下面的一个{1,3,5,2,4,6},那么可以看出里面奇数的相对位置是1,3,5,那么按照奇数开头的最后的序列也一定是{1,偶数,3,偶数,5,偶数};而按照偶数开头的序列一定是{2,奇数,4,奇数,6,奇数}。这样我们很容易就能知道按照这两种方法进行操作所能得到的最小次数,其实就是每一个相应的数的交换次数相加。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int maxn=1e5+10;
ll a[maxn];
void solve()
{
int n;
scanf("%d",&n);
ll ji=0;
ll ou=0;
ll ans1=0,ans2=0;
ll tnk=0,cnt=0;
for(int i=0;i<n;i++)
{
scanf("%lld",&a[i]);
if(a[i]%2==1)
{
ji++;
ans2+=abs(i-tnk*2);
tnk++;
}
else
{
ou++;
ans1+=abs(i-cnt*2);
cnt++;
}
}
if(abs(ji-ou)>1)
{
printf("-1\n");
return ;
}
else if(ou==ji)
{
printf("%lld\n",min(ans1,ans2));
}
else if(ou-ji==1)
{
printf("%lld\n",ans1);
}
else
{
printf("%lld\n\n",ans2);
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
solve();
}
return 0;
}
Compressed Bracket Sequence
题目意思和分析
给定一个序列,这个序列由n个数字构成,这n个数字中,奇数位置的数字表示左括号的数量,偶数位置的数字表示右括号的数量。问你,能够匹配的序列数量是多少。
然后就按照一个基本的思路来进行模拟,在模拟过程中要考虑到后面的数量收前面的括号情况的影响。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e3+5;
ll a[maxn],b[maxn];
ll min(ll a,ll b)
{
if(a<=b)return a;
else return b;
}
void solve()
{
int n,n2;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
if(i&1)
{
scanf("%lld",&a[(i+1)/2]);
}
else
{
scanf("%lld",&b[(i+1)/2]);
}
}
n2=n/2;
ll ans=0;
for(int i=1; i<=n2; i++)
{
ll h=0;
ll intern = -b[i];
for(int j=i; j>=1; j--)
{
h+=b[j];//总共剩余的右括号
intern+=b[j];//当前对的右括号
if(a[j]>h)
{
ans+= (h-intern);
if(intern)
ans++;
break;
}
if (a[j]>= intern)
{
ans+=a[j]-intern;
if (intern)
ans++;
}
intern-=min(a[j],intern);
h-=a[j];
}
}
printf("%lld\n",ans);
}
int main()
{
int t=1;
//scanf("%d",&t);
while(t--)
{
solve();
}
return 0;
}