多校 2009 2

A   

n  然后 n 个点  然后n个点

问 2个多边形 是不是相似的

1 极角排序   2 判断边长度成比例 3 对应的角度    好像没来卡精度

#include <iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
#include<math.h>

using namespace std ;

#define ll __int64
#define MAXN 310
#define inf  1000000007
#define exp  1e-8

struct point
{
    public:
        int x,y;
        int operator ^ (point b)
        {
            return x*b.y-y*b.x;
        }
        point operator -(point b)
        {
            point c;
            c.x=x-b.x;
            c.y=y-b.y;
            return c;
        }
}s1[MAXN],s2[MAXN];
double dis(point a,point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
bool cmp1(point a,point b)
{
    int tmp=((a-s1[1])^(b-s1[1]));
    if(tmp>0)
        return 1;
    if(tmp==0&&dis(a,s1[1])<dis(b,s1[1]))
        return 1;
    return 0;
}
bool cmp2(point a,point b)
{
    int tmp=((a-s2[1])^(b-s2[1]));
    if(tmp>0)
        return 1;
    if(tmp==0&&dis(a,s2[1])<dis(b,s2[1]))
        return 1;
    return 0;
}

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=1;i<=n;i++)
            scanf("%d%d",&s1[i].x,&s1[i].y);
        for(int i=1;i<=n;i++)
            scanf("%d%d",&s2[i].x,&s2[i].y);
        if(n==1||n==2)
            printf("Yes\n");
        else
        {
            int ind=1;
            for(int i=2;i<=n;i++)
            {
                if(s1[i].x<s1[ind].x)
                    ind=i;
                else if(s1[i].x==s1[ind].x&&s1[i].y<s1[ind].y)
                    ind=i;
            }
            swap(s1[1],s1[ind]);
            sort(s1+2,s1+n+1,cmp1);
            ind=1;
            for(int i=2;i<=n;i++)
            {
                if(s2[i].x<s2[ind].x)
                    ind=i;
                else if(s2[i].x==s2[ind].x&&s2[i].y<s2[ind].y)
                    ind=i;
            }
            swap(s2[1],s2[ind]);
            sort(s2+2,s2+n+1,cmp2);
            int ok=0;
            double k;
            k=dis(s1[1],s1[2])/dis(s2[1],s2[2]);
            s1[0]=s1[n];
            s1[n+1]=s1[1];
            s2[0]=s2[n];
            s2[n+1]=s2[1];

            for(int i=2;i<=n;i++)
            {
                double kk;
                kk=dis(s1[i],s1[i+1])/dis(s2[i],s2[i+1]);
                if(fabs(kk-k)>exp)
                    ok=1;
            }
            for(int i=1;i<=n;i++)
            {
                double a1,a2,a3,b1,b2,b3,c1,c2;
                a1=dis(s1[i],s1[i-1]);
                a2=dis(s1[i],s1[i+1]);
                a3=dis(s1[i-1],s1[i+1]);
                c1=(a1*a1+a2*a2-a3*a3)/(2*a1*a2);
                b1=dis(s2[i],s2[i-1]);
                b2=dis(s2[i],s2[i+1]);
                b3=dis(s2[i-1],s2[i+1]);
                c2=(b1*b1+b2*b2-b3*b3)/(2*b1*b2);
                if(fabs(c1-c2)>exp)
                    ok=1;
            }
            if(ok==1)
                printf("No\n");
            else
                printf("Yes\n");
        }
    }

    return 0;
}
View Code

E

给你n*m  的 0 1  矩阵  可以交换任意2列

求最大子矩阵  矩阵内部都是1

1  num[i] 第i列 连续下来的1的个数

0  num[i]=0  具体看代码

#include <iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
#include<math.h>

using namespace std ;

#define ll __int64
#define MAXN 1010
#define inf  1000000007
#define exp  1e-8

char z[MAXN][MAXN];
int num[MAXN],sum[MAXN];
bool cmp(int a,int b)
{
    return a>b;
}
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int i=1;i<=n;i++)
            scanf("%s",z[i]+1);
        memset(num,0,sizeof(num));
        memset(sum,0,sizeof(sum));
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(z[i][j]=='1')
                    num[j]++;
                else
                    num[j]=0;  //不能连续就清零
                sum[j]=num[j];
            }
            sort(sum+1,sum+m+1,cmp);
            for(int j=1;j<=m;j++) 
                ans=max(ans,j*sum[j]);  //前面的都比这个长  而且是上面连续下来的
        }
        printf("%d\n",ans);
    }
    return 0;
}
View Code

F

n个僵尸 豌豆的cd 

然后 僵尸的时间  hp

打hp的时间就能打死  一排只能放一个豌豆

按剩下的时间排序   走的时间-hp   其他不对

#include <iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
using namespace std ;

#define ll __int64
#define MAXN 30100
#define mod 200907


struct node
{
    int v,hp,ind;
}z[MAXN];
bool cmp(node a,node b)
{
    int a1,b1;
    a1=a.v-a.hp;
    b1=b.v-b.hp;
    return a1<b1;
}
int main()
{
    int n,t;
    while(scanf("%d%d",&n,&t)!=EOF)
    {
        for(int i=1;i<=n;i++)
        {
             scanf("%d%d",&z[i].v,&z[i].hp);
             z[i].ind=i;
        }
        sort(z+1,z+n+1,cmp);
        int ok=0;
        for(int i=1;i<=n;i++)
        {
            if(i*t+z[i].hp>z[i].v)
                ok=1;
        }
        if(ok==1)
            printf("The zombies eat your brains!\n");
        else
        {
            for(int i=1;i<n;i++)
                printf("%d ",z[i].ind);
            printf("%d\n",z[n].ind);
        }
    }
    return 0;
}
View Code

G

长度为  100cm

一只蜗牛 每秒走 k cm  走完了1s 人就会把跑道拉长100cm  但是 终点和当前蜗牛的位子的比例不变  然后继续上面的操作 问什时候走到终点  卡精度

调和级数n  1/1+1/2 + 1/3 ...  +1/n   = ln(n)+c + 1/(2*n)  n >10000  c=0.57721566490153286060651209  好像叫欧拉常数

反正卡精度了 

#include <iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
#include<math.h>

using namespace std ;

#define ll __int64
#define MAXN 30100
#define c  0.57721566490153286060651209
#define inf  1000000007

int main()
{
    int k;
    while(scanf("%d",&k)!=EOF)
    {
        if(k<=10)
        {
            int l=1,r=inf,ans;
            ans=inf;
            while(l<=r)
            {
                int mid=(l+r)>>1;
                if(k*(log(mid)+c+1.0/(2*mid))/100>=1)
                {
                    r=mid-1;
                    ans=min(ans,mid);
                }
                else
                    l=mid+1;
            }
            printf("%d\n",ans);
        }
        else
        {
            int i=1;
            double ans=0;
            while(1)
            {
                ans=ans+1.0*k/i;
                if(ans>=100)
                    break;
                i++;
            }
            printf("%d\n",i);
        }
    }

    return 0;
}
View Code

H

n个点 m条无向边

u v w 

然后  起点1 终点1  起点2 终点2

问起点1 -> 终点1  起点2->终点2 

他们的最短路径中 相同的点最多有多少个 

相同的点的是连续的   可以去画一画 

然后floyd  求最短路z[i][j]  然后求出 dp[i][j]  i 到j 经历最多点的数目

最后呢    列举  i j

s1 - > i -> j -> e1  s2->i ->j ->e2

只要是最短路的  那么ans =min(ans,dp[i][j]);

#include <iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
#include<math.h>

using namespace std ;

#define ll __int64
#define MAXN 1010
#define inf  1000000007
#define exp  1e-8

int  z[MAXN][MAXN];
int dp[MAXN][MAXN];

// 给定一个无向图,和两对起点终点,求两条最短路上的最多公共交点数。
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==0&&m==0)
            break;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                 if(i==j)
                {
                    dp[i][j]=1;
                    z[i][j]=0;
                }
                else
                {
                    dp[i][j]=2;
                    z[i][j]=inf;
                }
            }
        for(int i=1;i<=m;i++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            z[a][b]=z[b][a]=min(z[a][b],c);
        }
        for(int k=1;k<=n;k++)
        {
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    if(z[i][j]>z[i][k]+z[k][j])
                    {
                        z[i][j]=z[i][k]+z[k][j];
                        dp[i][j]=dp[i][k]+dp[k][j]-1;
                    }
                    else if(z[i][j]==z[i][k]+z[k][j]&&dp[i][j]<dp[i][k]+dp[k][j]-1)
                    {
                        dp[i][j]=dp[i][k]+dp[k][j]-1;
                    }
                }
            }
        }
        int s1,e1,s2,e2;
        scanf("%d%d%d%d",&s1,&e1,&s2,&e2);
        int ans=0;

        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(z[s1][i]+z[i][j]+z[j][e1]==z[s1][e1]&&z[s2][i]+z[i][j]+z[j][e2]==z[s2][e2])
                    ans=max(ans,dp[i][j]);
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
View Code

 

posted on 2017-05-19 21:31  HelloWorld!--By-MJY  阅读(172)  评论(0编辑  收藏  举报

导航