哎,上海站打的很烂,自己不会的还是太多,还有就是英语真的重要,热身赛就是因为翻译错了,然后题意弄错了
热身赛
A.Two Point Removal
题目大意:就是给你若干点的纵坐标,然后横坐标是1-n,然后在若干点中删除2个,然后使得(0,0)到(n+1,0)距离最短;
思路:先删除一个点,保证删除后使得路线最短,再删除下一个
#include <iostream>
#include <algorithm>
#include<cmath>
using namespace std;
const int M=1e6+7;
#define ll long long
int m;
double v[M];
struct node
{
int x;
int y;
}b[M];
double solve(node b1,node b2,node b3)
{
return sqrt(abs(b1.x-b2.x)*abs(b1.x-b2.x)+abs(b1.y-b2.y)*abs(b1.y-b2.y))+sqrt(abs(b3.x-b2.x)*abs(b3.x-b2.x)+abs(b3.y-b2.y)*abs(b3.y-b2.y))-sqrt(abs(b1.x-b3.x)*abs(b1.x-b3.x)+abs(b1.y-b3.y)*abs(b1.y-b3.y));
}
bool cmp(node a,node b)
{
return a.x<b.x;
}
int main()
{
cin>>m;
for(int i=1; i<=m; i++)
{
cin>>b[i].y;
b[i].x=i;
}
int u;
double maxx=0;
double sum=0;
b[m+1].y=0;
b[m+1].x=m+1;
for(int i=1; i<=m; i++)
{
sum+=sqrt(abs(b[i].x-b[i-1].x)*abs(b[i].x-b[i-1].x)+abs(b[i].y-b[i-1].y)*abs(b[i].y-b[i-1].y));
if(solve(b[i-1],b[i],b[i+1])>maxx)
{
u=i;
maxx=solve(b[i-1],b[i],b[i+1]);
}
}
b[u].x=1e6;
sum+=sqrt(abs(b[m].x-b[m+1].x)*abs(b[m].x-b[m+1].x)+abs(b[m].y-b[m+1].y)*abs(b[m].y-b[m+1].y));
sum-=maxx;
/* for(int i=0;i<=m+1;i++)
{
printf("%d %d\n",b[i].x,b[i].y);
}
printf("%.16lf\n",sum);*/
sort(b,b+m+2,cmp);
/*for(int i=0;i<=m;i++)
{
printf("%d %d\n",b[i].x,b[i].y);
}*/
maxx=0;
for(int i=1; i<=m-1; i++)
{
if(solve(b[i-1],b[i],b[i+1])>maxx)
{
u=i;
maxx=solve(b[i-1],b[i],b[i+1]);
}
}
sum-=maxx;
printf("%.16lf\n",sum);
return 0;
}
正式赛
D.Strange_Fractions
题目大意:解方程。使得上述p/q=a/b+b/a;
思路:首先需要约分成为最简形式,然后通过约分,你可以得到(a+b)平方=p+2q,a-b的平方=p-2q,因为a,b为整数,所以p+2q和p-2q都是平方数,如果不是输出0 0,然后(sqrt(p+2q)+sqrt(p-2q))/2,就是其中一个数,然后a+b也知道,就可以求出另一个数
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
#define ll long long
const ll M=1e6+7;
int main()
{
ll m,n;
ll T;
ll ans,bns;
scanf("%lld",&T);
while(T--)
{
scanf("%lld%lld",&m,&n);
ll L=__gcd(m,n);
m/=L,n/=L;
ans=m+2*n;
bns=m-2*n;
ll mm=sqrt(ans);
ll oo=sqrt(bns);
if(mm*mm!=ans||oo*oo!=bns)
{
printf("0 0\n");
continue;
}
ll qq=(sqrt(ans)+sqrt(bns))/2;
ll nn=mm-qq;
printf("%lld %lld\n",min(nn,qq),max(nn,qq));
}
return 0;
}
E.Strange_Integers(签到题)
题目大意:给你若干数和k,让你计算出可以选出多少数,保证它们之间的距离都大于等于K
思路:排序,去重,遍历,判断
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
#define ll long long
const ll M=1e5+7;
ll s[M],p[M];
int main()
{
ll m,n;
ll T;
ll ans;
cin>>m>>n;
for(int i=1;i<=m;i++)
{
scanf("%d",&s[i]);
}
sort(s+1,s+1+m);
/* for(int i=1;i<=m;i++)
{
printf("%d",s[i]);
}*/
p[1]=s[1];
int j=2;
for(int i=2;i<=m;i++)
{
if(s[i]!=s[i-1])
{
p[j]=s[i];
j++;
}
}
/*for(int i=1;i<=j-1;i++)
{
printf("%d",p[i]);
}
*/
ans=1;
ll bns=p[1];
for(int i=2;i<=j-1;i++)
{
if(p[i]-bns>=n)
ans++,bns=p[i];
}
printf("%lld\n",ans);
return 0;
}