Codeforces Round #191 (Div. 2).

前天的比賽今天才寫總結,自己的生活是越來越亂了,整天都不知道做什麼,下午同學來找我玩,好高興啊!

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第一次做到紅色,水平太差了~


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章