Codeforces Round #616 (Div. 2)
A. Even But Not Even
题意
输入一个位数不超过3000的数,删除其中的若干位,把它变成一个自身为奇数,所有位上的数之和为偶数的数。
题解
用字符串把数存起来,先找到最后一个为奇数的位置,将起后面的全部删掉,然后把剩下的数加起来,如果得到奇数,就在字符串中找一位奇数将其删掉,最后处理前导零。
代码
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{ long N,i,n;
long long sum;
string s;
cin>>N;
while(N--){
cin>>n>>s;
while((s[s.length()-1]-'0')%2==0&&s.length()>1)
s.erase(s.length()-1);
sum=0;
for(i=0;i<s.length();i++)
sum+=s[i]-'0';
if(sum%2)
for(i=0;i<s.length()-1;i++)
if((s[i]-'0')%2==1){
s.erase(i,1);
break;
}
while(s[0]=='0')
s.erase(0,1);
sum=0;
for(i=0;i<s.length();i++)
sum+=s[i]-'0';
if((s[s.length()-1]-'0')%2&&sum%2==0)
cout<<s<<endl;
else
cout<<-1<<endl;
}
return 0;
}
B. Array Sharpening
题意
有n个数形成的数列,可以对其中的所有数进行减法操作,问是否做到将其变成金字塔形。
题解
考虑到只能进行减法操作,故要想办法将所有数的需求最小化,容易证明到,在需求最小化后,最大点一定出现在中间位置。下面分两种情况:
1)当n为奇数时
最大点必然出现在n/2+1的位置上,故只要从头尾分别向中间循环判断即可
2)当n为偶数时
因为无法严格按照金字塔分布,所以有两种可能:
要么左边向右上多延伸半格,此时最大值出现在n/2的位置,
要么右边向左上多延伸半格,此时出现在n/2+1的位置。
故两端分别向中间判断,最后单独判断中间两个即可
代码
#include<cstdio>
#define def 300010
long a[def];
int main()
{ long N,n,i;
bool t;
scanf("%ld",&N);
while(N--){
scanf("%ld",&n);
t=true;
for(i=1;i<=n;i++)
scanf("%ld",&a[i]);
for(i=1;i<=n/2;i++)
if(a[i]<i-1)
t=false;
for(i=n/2+1;i<=n;i++)
if(a[i]<n-i)
t=false;
if(n%2==0)
t&=(a[n/2]>=n/2||a[n/2+1]>=n/2);
if(t)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
C. Mind Control
题意
m个人在n个数里取数,每人可以在数列的开头或结尾取一个,自己是最后一个取数的,在所有人开始前,你可以强迫k个人一定取开头的或结尾的,每个人强迫的内容可以不同,问可以保证自己至少取多少
题解
先用最基本的搜索思想,无论是否强迫,n个数里被取掉的m-1个数一定在首尾
如当m=4,k=0时,被取走的可能有a4,a5,a6或a1,a5,a6或a1,a2,a6或a1,a2,a3
被取走之后,我们可以任意取走剩下的首尾中较大的数,即max(a1,a3),max(a2,a4),max(a3,a4),max(a4,a6)
因为问的是至少,所以在这四个里面取得的最小值就是答案
但是现在加入了k值,这k个人的取法是我们可以控制的,由于需要确定性的答案,所以这k个人一定会先取
还是n=6,m=4,现在增加条件k=2
我们可以强迫取走a5,a6或a1,a6或a1,a2
然后在剩下的4个数中,又被随机取走m-1-k=1个数
取走后剩下的n-(m-1)=3个数中,首尾最大的就是当前的局部最优,记作ans1
由上面k=0的情况可以推出,强迫取走k个后的局部最优是min{ans1},记作ans2
因为k个可控,那么肯定要选最优取法,所以全局最优是max{ans2}
综上,可以用两个区间来加以限制
第一个是取走k个后的区间,这个区间的最大值就是全局最优
第二个是再取走m-1-k个后的区间,这个区间的最小值就是局部最优
剩下的区间首尾的最大值就是最优
代码
#include<cstdio>
#define min(a,b) (((a)<(b))?(a):(b))
#define max(a,b) (((a)>(b))?(a):(b))
#define def 4000
#define INF ~(1<<31)
long a[def];
int main()
{ long N,n,m,k,i,j,minn,ans=0;
scanf("%ld",&N);
while(N--){
scanf("%ld%ld%ld",&n,&m,&k);
ans=0;
for(i=1;i<=n;i++)
scanf("%ld",&a[i]);
if(k>=m)
for(i=1;i<=m;i++)
ans=max(ans,max(a[i],a[i+n-m]));
else for(i=1;i<=k+1;i++){
minn=INF;
for(j=0;j<=m-k-1;j++)
minn=min(minn,max(a[i+j],a[i+n-m+j]));
ans=max(ans,minn);
}
printf("%ld\n",ans);
}
return 0;
}