A.Split it!
题意:判断一个字符串是否能使得这条件:s=a1+a2+…+ak+ak+1+R(ak)+R(ak−1)+…+R(a1).成立,并且R(abcd)=dcba。
思路:只需要从两头看,把中间看做a(k+1),所以只要两头相同的字符个数大于等于k即可。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t,i,j,n,k;
string s1;
cin>>t;
while(t--){
cin>>n>>k>>s1;
// cout<<s1.length()<<endl;
if(k==0){
cout<<"YES"<<endl;
}
else if(k+k+1>n){
cout<<"NO"<<endl;
}
else {
int cnt=0;
for(i=0;i<s1.length()/2;i++){
if(s1[i]==s1[s1.length()-1-i]){
cnt++;
}
else {
break;
}
}
if(cnt>=k){
cout<<"YES"<<endl;
}
else {
cout<<"NO"<<endl;
}
}
}
}
B. Max and Mex
题意:有k次操作,每次操作将从0开始数第一个没出现的数字加上数组里出现最大的一个数相加除以2。
思路:乱搞一下能找到规律,因为数组里都是不重复的数,所以如果是一个从0开始的全排列,那么最后数就有n+1个,否则就判断(max+mex)/2所放入的新值有没有出现过并且要判断操作次数要有一次才行。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+1000;
int a[maxn];
int main()
{
int t,i,j,n,k;
cin>>t;
while(t--){
cin>>n>>k;
map<int ,int >mo;
for(i=0;i<n;i++){
cin>>a[i];
mo[a[i]]=1;
}
sort(a,a+n);
int d1=0,max1=a[n-1];
for(i=0;i<n;i++){
if(d1==a[i]){
d1++;
continue;
}
else {
break;
}
}
//cout<<d1<<" "<<max1<<endl;
if(d1==max1+1){
cout<<n+k<<endl;
}
else {
int m1=(max1+d1)%2==0?(max1+d1)/2:(max1+d1)/2+1;
if(mo[m1]==0&&k>=1){
cout<<n+1<<endl;
}
else {
cout<<n<<endl;
}
}
}
}
C. Diamond Miner
题意:分别给你x轴上n个点和y轴上n个点,求两两相连所构成的三角形的斜边和最小。
思路:直接排序既可。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+1000;
double x[maxn],y[maxn];
bool cmp(double x1,double y1){
return x1>y1;
}
int main()
{
int t,i,j,n;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
double sum=0;
int cnt1=0,cnt2=0,x1,y1;
for(i=0;i<2*n;i++){
scanf("%d%d",&x1,&y1);
if(x1==0) y[cnt1++]=abs(y1);
if(y1==0) x[cnt2++]=abs(x1);
}
sort(y,y+n);
sort(x,x+n);
int zs1=0,zs2=n-1,ys1=0,ys2=n-1;
for(i=0;i<n;i++){
sum+=sqrt(x[i]*x[i]+y[i]*y[i]);
}
printf("%.16lf\n",sum);
}
}