• 组队练习 2011年福州全国邀请赛


    A 水题。

    B 计算几何求重心,枚举对称点。

    #include <string.h>
    #include <algorithm>
    #include <stdio.h>
    #include <cmath>
    #include <iostream>
    using namespace std;
    #define maxn 600
    #define eps 1e-6
    bool zero(double a) {return (fabs(a)<eps?1:0);}
    struct point{
        double x,y;
    }po[maxn],center;
    int n;
    struct line{
        point a,b;
    };
    double cross1(point &a,point &b,point &c){
        return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
    }
    double cross(point p1,point p2,point p0){
        return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
    }
    point intersection(line u,line v){
        point ret=u.a;
        double t=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x))/((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x));
        ret.x+=(u.b.x-u.a.x)*t;
        ret.y+=(u.b.y-u.a.y)*t;
        return ret;
    }
    point barycenter(point a,point b,point c){
        line u,v;
        u.a.x=(a.x+b.x)/2;
        u.a.y=(a.y+b.y)/2;
        u.b=c;
        v.a.x=(a.x+c.x)/2;
        v.a.y=(a.y+c.y)/2;
        v.b=b;
        return intersection(u,v);
    }
    point barycenter(int n,point *p){
        point ret,t;
        double t1=0,t2;
        int i;
        ret.x=ret.y=0;
        for(i=1;i<n-1;i++){
            if(fabs(t2=cross(p[0],p[i],p[i+1]))>eps){
                t=barycenter(p[0],p[i],p[i+1]);
                ret.x+=t.x*t2;
                ret.y+=t.y*t2;
                t1+=t2;
            }
        }
        if(fabs(t1)>eps)
            ret.x/=t1,ret.y/=t1;
        return ret;
    }
    double dmult(point &a,point &b){
        return a.x*b.x+a.y*b.y;
    }
    double dmult(double a,double b,double c,double d){
        return a*c+b*d;
    }
    bool is_ok(int l,int r,int a,int b){
        if(r<l)return true;
        point temp,t;
        while(l<r){
            temp.x=(po[l].x+po[r].x)/2;
            temp.y=(po[l].y+po[r].y)/2;
             if(!zero(dmult(po[l].x-po[r].x,po[l].y-po[r].y,temp.x-center.x,temp.y-center.y)))
                return false;
             l++,r--;
        }
        temp.x=(po[a].x+po[b].x)/2;
        temp.y=(po[a].y+po[b].y)/2;
        if(l==r)
        return zero(cross(temp,center,po[l]));
        return true;
    }
    bool sovle(){
        int i,k;
        point temp;
        for(i=1;i<n;i++){
            temp.x=(po[0].x+po[i].x)/2;
            temp.y=(po[0].y+po[i].y)/2;
            if(zero(dmult(po[i].x-po[0].x,po[i].y-po[0].y,temp.x-center.x,temp.y-center.y))){
                    if(is_ok(1,i-1,0,i)&& is_ok(i+1,n-1,0,i))
                    return true;
            }
        }
         for(i=2;i<n;i++){
            temp.x=(po[1].x+po[i].x)/2;
            temp.y=(po[1].y+po[i].y)/2;
            if(zero(dmult(po[i].x-po[1].x,po[i].y-po[1].y,temp.x-center.x,temp.y-center.y))){
                //printf("HHHH%lf %lf
    ",po[i].x,po[i].y);
                    if(is_ok(2,i-1,1,i)&& is_ok(i+1,n,1,i))
                    return true;
            }
        }
        return false;
    }
    int main(){
        int i,j,k,t,cas=0;
        scanf("%d",&t);
        while(t--){
    
            scanf("%d",&n);
            for(i=0;i<n;i++)
            scanf("%lf%lf",&po[i].x,&po[i].y);
            k=1;
            for(i=2;i<n;i++){
                if(zero(cross(po[k-1],po[k],po[i])))
                po[k]=po[i];
                else po[++k]=po[i];
            }
            k++;
            if(zero(cross(po[0],po[k-1],po[k-2])))
            k--;
            if(zero(cross(po[k-1],po[0],po[1]))){
                    for(i=1;i<k;i++)
                     po[i-1]=po[i];
                     k--;
            }
            n=k;
            printf("Case %d: ",++cas);
            if(k<=2){
                printf("YES
    ");
                continue;
            }
            po[n]=po[0];
            center=barycenter(n,po);
            if(sovle())
                printf("YES
    ");
            else
                printf("NO
    ");
        }
        return 0;
    }

    C 数学题。

    import java.math.*;
    import java.math.BigDecimal;
    import java.util.*;
    public class Main {
        public static void main(String arg[]){
            BigDecimal a,b,c,x,y,z,d,an,ans;
            Scanner cin=new Scanner(System.in);
            int t=1,tt;
            tt=cin.nextInt();
            an=BigDecimal.valueOf(32);
            while(tt-->0){
                a=cin.nextBigDecimal();
                b=cin.nextBigDecimal();
                if(a.compareTo(b)>0){
                    c=a.subtract(b);
                    d=b;
                    ans=a;
                }else{
                    c=b.subtract(a);
                    d=a;
                    ans=b;
                }
                if(c.compareTo(an)<0){
                    double s=c.doubleValue();
                    s=Math.pow(2.0,s)+1;
                    s=Math.log(s)/Math.log(2.0);
                    ans=d;
                    ans=ans.add(BigDecimal.valueOf(s));
                }
                ans = ans.setScale(9, BigDecimal.ROUND_HALF_UP);
                System.out.println("Case "+t+": "+ans);
                t++;
            }
        }
    }

    D 数学

    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<iomanip>
    #include<cstdio>
    #define ll long long
    #define M 1000001
    #define mod 1000000007
    using namespace std;
    ll an[M];
    double p[M];
    void init()
    {
        an[0]=0;an[1]=1;
        p[0]=0;p[1]=1;
        ll t=1;
        for(int i=2;i<M;i++){
            an[i]=(i*an[i-1]%mod+t)%mod;
            t=(t*i)%mod;
            p[i]=p[i-1]+1.0/(double)i;
        }
    }
    int main()
    {
        int t,n,ca=0;
        init();
        scanf("%d",&t);
        while(t--){
            scanf("%d",&n);
            printf("Case %d: %I64d %.6lf
    ",++ca,an[n],p[n]);
        }
        return 0;
    }

    E 树形DP。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define Maxn 100010
    #define LL __int64
    using namespace std;
    int son[Maxn],vi[Maxn],head[Maxn],e;
    struct Edge{
        int u,v,next;
        LL val;
    }edge[Maxn*3];
    LL ans,sum;
    void add(int u,int v,LL val)
    {
        edge[e].u=u,edge[e].v=v,edge[e].val=val,edge[e].next=head[u],head[u]=e++;
        edge[e].u=v,edge[e].v=u,edge[e].val=val,edge[e].next=head[v],head[v]=e++;
    }
    void init()
    {
        memset(son,0,sizeof(son));
        memset(vi,0,sizeof(vi));
        memset(head,-1,sizeof(head));
        e=0;
    }
    void dfs(int u)
    {
        int i,v;
        son[u]=1;
        vi[u]=1;
        for(i=head[u];i!=-1;i=edge[i].next){
            v=edge[i].v;
            //cout<<u<<" "<<v<<" ";
            if(vi[v]) continue;
            dfs(v);
            //cout<<son[v]<<" "<<sum<<" "<<edge[i].val<<endl;
            ans+=son[v]*(sum-son[v])*2*edge[i].val;
            son[u]+=son[v];
        }
    }
    int main()
    {
        int t,n,a,b,i,j,Ca=0;
        LL c;
        scanf("%d",&t);
        while(t--){
            init();
            scanf("%d",&n);
            for(i=1;i<n;i++){
                scanf("%d%d%I64d",&a,&b,&c);
                a++,b++;
                add(a,b,c);
            }
            ans=0;
            sum=n;
            dfs(1);
            printf("Case %d: %I64d
    ",++Ca,ans);
        }
        return 0;
    }

    F 是个最大匹配

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #define Maxn 110
    using namespace std;
    int match[Maxn],n,m;
    bool g[Maxn][Maxn],vi[Maxn];
    int dfs(int u)
    {
        int i;
        for(i=1;i<=m;i++){
            if(!vi[i]&&g[u][i]){
                vi[i]=1;
                if(match[i]==-1||dfs(match[i])){
                    match[i]=u;
                    return true;
                }
            }
        }
        return false;
    }
    int main()
    {
        int t,e,i,j,u,v,Ca=0;
        scanf("%d",&t);
        while(t--){
            scanf("%d%d%d",&n,&m,&e);
            memset(g,1,sizeof(g));
            for(i=1;i<=e;i++){
                scanf("%d%d",&u,&v);
                g[u][v]=0;
            }
            memset(match,-1,sizeof(match));
            int ans=0;
            for(i=1;i<=n;i++){
                memset(vi,0,sizeof(vi));
                if(dfs(i))
                    ans++;
            }
            printf("Case %d: %d
    ",++Ca,ans);
        }
        return 0;
    }

     先O(n)预处理出ri[i][j],le[i][j],分别表示第i个位置向右边移动出j个空格需要的步数,表示第i个位置向左边移动出j个空格需要的步数。

    然后枚举间隙处,二分判段最大间隔。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define Maxn 710
    #define inf 100000000
    using namespace std;
    int ri[Maxn][Maxn],le[Maxn][Maxn],n,m;
    char str[Maxn];
    bool OK(int pos,int x)
    {
        int i,j,cnt=inf;
        if(pos==1) {
            cnt=min(cnt,ri[pos][x]);
            return cnt<=m;
        }
        for(i=0;i<=n;i++){
            if(i>x) break;
            cnt=min(cnt,ri[pos][i]+le[pos-1][x-i]);
        }
        //cout<<pos<<" "<<x<<" "<<cnt<<" "<<m<<endl;
        return cnt<=m;
    }
    int main()
    {
        int t,i,j,ze,Ca=0;
        scanf("%d",&t);
        while(t--){
            for(i=1;i<Maxn;i++){
                for(j=1;j<Maxn;j++){
                    ri[i][j]=le[i][j]=inf;
                }
            }
            ze=0;
            scanf("%d%d%s",&n,&m,str);
            if(str[0]=='0') le[1][1]=0,ze=1;
            for(i=1;i<n;i++){
                if(str[i]=='0') ze++;
                for(j=1;j<=n;j++){
                    if(le[i][j-1]>=inf) break;
                    if(str[i]=='1')
                        le[i+1][j]=le[i][j]+j;
                    else
                        le[i+1][j]=le[i][j-1];
                }
            }
            if(str[n-1]=='0') ri[n][1]=ri[n+1][1]=0;
            for(i=n-1;i>=1;i--){
                for(j=1;j<=n;j++){
                    if(ri[i+1][j-1]>=inf) break;
                    if(str[i-1]=='1')
                        ri[i][j]=ri[i+1][j]+j;
                    else
                        ri[i][j]=ri[i+1][j-1];
                }
            }
            int f=0;
            int ans=0,l,r,mid;
            for(i=1;i<=n;i++){
                if(str[i-1]=='0'){
                    l=0;r=ze;
                    while(l+1<r){
                        mid=(l+r)>>1;
                        if(OK(i,mid))
                            l=mid;
                        else
                            r=mid;
                    }
                    ans=max(ans,l);
                    if(OK(i,r))
                        ans=max(ans,r);
                }
            }
            printf("Case %d: %d
    ",++Ca,ans);
        }
        return 0;
    }
  • 相关阅读:
    Crontab '2>&1 &' 含义
    form提交方式Methor
    oracle基本术语
    在工作中常用的sql语句
    常用的删除大数据方法(游标+分段)
    oracle9i、10g、11g区别
    SSH面试总结(Hibernage面试)
    实习生招聘笔试
    TopCoder上一道600分滴题
    Oracle数据库面试题汇总
  • 原文地址:https://www.cnblogs.com/wangfang20/p/3353680.html
Copyright © 2020-2023  润新知