前天的比赛今天才写总结,自己的生活是越来越乱了,整天都不知道做什么,下午同学来找我玩,好高兴啊!
B. Maximal Area Quadrilateral
题意:给定一个点集,随意找一个四边形,使得四边形的面积最大,可以不是凸的!
解题思路:向量的叉积,不断的枚举对角线,然后求两边的点到对角线组成的三角形的面积最大,两边三角形面积最大的相机即可,要考虑两边都要存在点,一边没点的情况是不允许的!
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<climits>
#include<map>
using namespace std;
#define rep(i,n) for(int i=0; i<n; i++)
#define repf(i,n,m) for(int i=(n); i<=(m); ++i)
#define repd(i,n,m) for(int i=(n); i>=(m); --i)
#define ll long long
#define arc(a) ((a)*(a))
#define inf 100000
#define exp 0.000000001
#define N 305
struct node{
int x,y;
};
node a[N];
int n;
double mul(node a,node b,node c)
{
double x=a.x-c.x,y=a.y-c.y;
double xx=b.x-c.x,yy=b.y-c.y;
return (x*yy-y*xx)*0.5;
}
int main()
{
while(~scanf("%d",&n))
{
rep(i,n) scanf("%d%d",&a[i].x,&a[i].y);
double Max=0;
double Maxl=0,Maxr=0;
rep(i,n)
{
repf(j,i+1,n-1)
{
Maxl=Maxr=0;
int flag=0,sign=0;
rep(k,n)
{
if(k==i || k==j) continue;
double s=mul(a[i],a[j],a[k]);
if(s<exp)
Maxl=max(Maxl,-s),flag=1;
else
Maxr=max(Maxr,s),sign=1;
}
if(flag==1 && sign==1)
Max=max(Max,Maxl+Maxr);
}
}
printf("%0.9lf\n",Max);
}
return 0;
}
C. Tourist Problem
题意:给定n个数,从0出发,可以先到任意一点,求n!的路的平均距离。
思路:比赛的时候大致分析了一下,如果纯暴力则最后要除n!,但是因为每一位算的时候都含有(n-1)!,所以可以直接约去,暴力求得每个点到另外所有点的距离即可!
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<climits>
#include<map>
using namespace std;
#define rep(i,n) for(int i=0; i<n; i++)
#define repf(i,n,m) for(int i=(n); i<=(m); ++i)
#define repd(i,n,m) for(int i=(n); i>=(m); --i)
#define ll long long
#define arc(a) ((a)*(a))
#define inf 100000
#define exp 0.000001
#define N 200005
ll a[N];
int n;
ll sum,ans;
ll gcd(ll x,ll y)
{
if(x<y) swap(x,y);
if(y==0) return x;
return gcd(y,x%y);
}
int main()
{
while(cin>>n)
{
rep(i,n)
scanf("%I64d",&a[i]);
sort(a,a+n);
sum=0;
rep(i,n) sum+=a[i];
ans=sum;
ll l=0;
rep(i,n)
{
ans+=(a[i]*i-l);
l+=a[i];
ans+=(sum-l-(n-i-1)*a[i]);
}
l=n;
l=gcd(ans,l);
ans/=l;
n/=l;
cout<<ans<<" "<<n<<endl;
}
return 0;
}
D. Bubble Sort Graph
题意:给定一个无序的序列以及一段代码,使得执行这段代码之后求得任意两个不想连的点的最大数量。
分析:题中的代码使得无序的序列变成单调递增序列,并且当大的小的左边进行交换时,添加一条大的到小的边,据此分析,对于任意一个数,在其右边并且比它小的数都会与他相连,由此可以转换为求最长递增子序列,直接贴模板就行了!
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<climits>
#include<map>
using namespace std;
#define rep(i,n) for(int i=0; i<n; i++)
#define repf(i,n,m) for(int i=(n); i<=(m); ++i)
#define repd(i,n,m) for(int i=(n); i>=(m); --i)
#define ll long long
#define arc(a) ((a)*(a))
#define inf 100000
#define exp 0.000001
#define N 100005
int a[N];
int q[N];
int n;
int main()
{
while(~scanf("%d",&n))
{
repf(i,1,n) scanf("%d",&a[i]);
q[0]=-inf;
int len=0;
repf(i,1,n)
{
if(a[i]>q[len])
q[++len]=a[i];
else
{
int l=1,r=len;
while(l<=r)
{
int mid=(l+r)/2;
if(q[mid]<=a[i])
l=mid+1;
else
r=mid-1;
}
q[l]=a[i];
}
}
printf("%d\n",len);
}
return 0;
}
做cf第一次做到红色,水平太差了~