前天的比賽今天才寫總結,自己的生活是越來越亂了,整天都不知道做什麼,下午同學來找我玩,好高興啊!
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第一次做到紅色,水平太差了~