2024 暑假友谊赛-热身1
1.B
原题链接:
https://vjudge.net/problem/AtCoder-arc100_a
这是一个单峰函数,可以采取三分的方式求极值
查看代码
#include<bits/stdc++.h>
#define int long long
const int N=1e6;
using namespace std;
int n,mi;
int a[1000000];
int check(int x)
{
int sum=0;
for(int i=1;i<=n;i++)
{
sum+=abs(a[i]-x);
}
return sum;
}
signed main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
a[i]-=i;
}
sort(a+1,a+n+1);
int l=-2e9,r=2e9;
mi=LLONG_MAX;
while(l<r-3)
{
int mid1=l+r>>1;
int mid2=mid1+r>>1;
if(check(mid1)>check(mid2))l=mid1;
else r=mid2;
}
for(int i=l-10;i<=l+10;i++)
mi=min(mi,check(i));
cout<<mi;
return 0;
}
2.E
原题链接:
https://vjudge.net/problem/CodeForces-1808C
组合排列并枚举,以l为数位准进行判断
查看代码
#include<bits/stdc++.h>
#define int long long
const int N=1e6;
using namespace std;
int n;
int a[1000000];
signed main()
{
cin>>n;
while(n--)
{
int l,r;
cin>>l>>r;
auto check=[&](int L,int R){//这个函数是在l的数位范围下对不同数组合成新数的判断,条件都满足就 return,这样可以满足数位差最小化
if(L==0&&L==R)return -1ll;//例如L=3,R=4,那么当i为0,t为5时的最大最小值是33333和34444
int sum=0;
int t=to_string(l).size();
for(int i=0;i<t;i++)
{
int biao=-1;
for(int j=L;j<=R;j++)
{
int ans=sum*10+j;
for(int k=i+1;k<t;k++)
{
ans=ans*10+L;
}
if(ans<=r&&ans>=l)
{
return ans;
}
if(ans>r) break;
ans=sum*10+j;
for(int k=i+1;k<t;k++)
{
ans=ans*10+R;
}
if(ans<l)continue;
biao=j;
break;
}
if(biao==-1)
{
return -1ll;
}
sum=sum*10+biao;
}
return sum;
};
int mi=LLONG_MAX;
int tmp=0;
for(int i=0;i<=9;i++)
{
for(int j=i;j<=9;j++)
{//不同的数种类随机组合
int x=check(i,j);
if(x!=-1)
{
if(j-i<mi)
{
mi=j-i;
tmp=x;
}
}
}
}
cout<<tmp<<endl;
}
return 0;
}