zoukankan      html  css  js  c++  java
  • 第四届福建省大学生程序设计竞赛

    FZU2140  Forever 0.5

    题意:构造一些点使得满足一些条件

    思路:把1个点放在(0,0)然后n-1点平均分在60度的圆弧上,这样也就是有n-1对点距离为1.0

    因为是60°所以n-1里面有一对点距离是1.0

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<map>
    #include<cmath>
    #include<queue>
    #include<cstring>
    #include<set>
    #include<stack>
    #include<string>
    #include<ctime>
    #define LL long long
    #define maxn 50
    #define MAX 700010
    #define mod  1000000007
    #define INF 0x3f3f3f3f
    #define eps 1e-5
    using namespace std;
    const double pi = acos(-1.0) ;
    
    struct point
    {
        double x , y ;
        point(){};
        point( double xx , double yy )
        {
            x = xx ; y = yy ;
        }
    } ;
    point operator - ( point a , point b )
    {
        return point( b.x-a.x , b.y-a.y ) ;
    }
    double cross( point a  , point b )
    {
        return a.x*b.y - a.y*b.x ;
    }
    
    int cmp( point a , point b )
    {
        return a.y < b.y || a.y == b.y && a.x < b.x ;
    }
    double get_erea(point *p,int n)
    {
        double ans=0;
        for(int i = 1 ; i < n-1 ;i++)
        {
            ans += cross(p[i]-p[0],p[i+1]-p[0]) ;
        }
        return ans/2;
    }
    double len(point a,point b)
    {
        return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    point Rotate(point a,double rad)
    {
        return point(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad)) ;
    }
    void out(point *p,int n )
    {
        for( int i = 0 ; i < n ;i++)
            printf("%.6lf %.6lf
    ",p[i].x,p[i].y) ;
    }
    bool check(point *p,int n )
    {
        int ans=0,i,j;
        for( i = 0 ; i < n ;i++)
            for( j = i+1 ; j< n;j++)
        {
            double u = len(p[i],p[j]) ;
            if(fabs(u-1.0) <eps)ans++;
            else if(u>1.0) return false;
        }
        if(ans==n) return true;
        return false;
    }
    int main()
    {
        int T,case1=0,n ;
        int i,j,k,u,v,ans;
        point p[110],aa ;
        double rad;
        cin >> T ;
        while(T--)
        {
             scanf("%d",&n) ;
             if(n<=3)
             {
                 puts("No");
                 continue ;
             }
             p[0].x=0;
             p[0].y=0;
             p[1].x=1;
             p[1].y=0;
             aa=p[1] ;
             rad=pi/3;
             rad /= (n-2);
             for(i = 2 ; i < n ;i++)
             {
                aa=Rotate(aa,rad) ;
                p[i]=aa;
             }
             double ans=get_erea(p,n) ;
            // printf("%.6lf
    ",ans) ;
              //   cout<<check(p,n) << endl;
             if(ans+eps>=0.5&&ans<=0.75)
             {
                 puts("Yes") ;
                 out(p,n) ;
             }
             else puts("No") ;
        }
        return 0;
    }
    View Code

    FZU2141 Sub-Bipartite Graph

    题意:取出原图的一个子图,这个图是二分图,有至少m/2条边

    思路:设二分图的两个部分是A,B,开始所有点在B里面。每次寻找最多度数(去掉A里面的点)的一个点放到A里面,然后判断是否满足要求

    没有就继续上面过程。

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<map>
    #include<cmath>
    #include<queue>
    #include<cstring>
    #include<set>
    #include<stack>
    #include<string>
    #include<ctime>
    #define LL long long
    #define u64 unsigned long long
    #define maxn 100010
    #define mod  1000000007
    #define INF 1000010
    #define eps 1e-5
    using namespace std;
    
    vector<int>qe[110],ans ;
    int in[110];
    bool vi[110] ,hehe[110];
    
    int find(int n)
    {
        memset(in,0,sizeof(in)) ;
        for(int i = 1 ; i <= n ;i++)if(!hehe[i])
        {
            for(int j = 0 ; j < qe[i].size();j++)
            {
                int v = qe[i][j] ;
                if(!hehe[v])in[i]++ ;
            }
        }
        int id=INF,Max=0;
        for( int i = 1 ; i <= n;i++)if(!hehe[i])
        {
            if(Max<in[i])
            {
                Max=in[i] ;
                id=i;
            }
        }
        return id;
    }
    bool check(int n,int m)
    {
        int cnt=0;
        for(int i = 1 ; i <= n ;i++)if(hehe[i])
        {
            for( int j = 0 ; j < qe[i].size();j++)
            {
                int v = qe[i][j] ;
                if(!hehe[v])cnt++;
            }
        }
        if(cnt>=m/2) return true;
        return false;
    }
    int main()
    {
        int i,j,n,m,k;
        int u,v,len ,cnt ;
        int T;
        cin >> T ;
        while(T--)
        {
            scanf("%d%d",&n,&m) ;
            ans.clear();
            for( i = 1 ; i <= n ;i++)
            {
                hehe[i]=false;
                qe[i].clear();
            }
            for( i = 1 ; i <= m;i++)
            {
                scanf("%d%d",&u,&v) ;
                qe[u].push_back(v) ;
                qe[v].push_back(u) ;
            }
            len=0;
            while(true)
            {
                k=find(n) ;
                if(k==INF) break ;
                hehe[k]=true;
                ans.push_back(k) ;
                if(check(n,m)) break ;
            }
            cout << ans.size() ;
            for( i = 0 ; i < ans.size();i++)
                cout << " " << ans[i] ;
            puts("") ;
            cout << n-ans.size() ;
            for( i = 1 ; i <= n ;i++)
            {
                if(!hehe[i]){
                        printf(" %d",i) ;
                }
            }
            puts("") ;
        }
        return 0 ;
    }
    View Code

    FZU2143 Board Game

    题意:不好说

    思路:棋盘模型,用最小费用流做。

    (a-b)^2 = a*a-2*a*b+b*b,b是常数,忽略。

    对于偶数的格子,源点连向它k条边,第i条边的流量为1,花费是 i-1增加到i的代价

    也就是 2*i-1-2*b

    对于奇数的格子也是一样,不过是它连向汇点

    然后奇数格子向相邻的格子连边,代价 0,流量INF

    在跑最小费用流的时候,如果dis[t] >= 0 那么就可以退出了,

    因为如果加上,那么总的代价就会增加

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<map>
    #include<cmath>
    #include<queue>
    #include<cstring>
    #include<set>
    #include<stack>
    #include<string>
    #include<ctime>
    #define LL long long
    #define u64 unsigned long long
    #define maxn 100010
    #define mod  1000000007
    #define INF 1000010
    #define eps 1e-5
    using namespace std;
    
    struct node
    {
        int u,v,cap,flow,cost,next;
    }edge[maxn];
    int inf=INF,dis[1010],pre[10010],top;
    int head[10010];
    bool vis[10010] ;
    
    void add(int u,int v,int cap,int flow,int cost)
    {
        edge[top].u = u ;
        edge[top].v = v ;
        edge[top].cap = cap ;
        edge[top].flow = flow ;
        edge[top].cost = cost ;
        edge[top].next = head[u] ;
        head[u]=top++ ;
    }
    void Unit(int u,int v,int cap,int cost )
    {
        //cout<<u<<" "<<v<<endl;
        add(u,v,cap,0,cost);
        add(v,u,0,0,-cost) ;
    }
    void init()
    {
        memset(head,-1,sizeof(head)) ;
        top=0;
    }
    bool spfa(int s, int t)
    {
        queue<int>q;
        // why
        for (int i = 0; i < 1010; i++)
        {
            dis[i] = inf;
            vis[i] = false;
            pre[i] = -1;
        }
        dis[s] = 0;
        vis[s] = true;
        q.push(s);
        while (!q.empty())
        {
            int u = q.front();
            q.pop();
            vis[u] = false;
            for (int i = head[u]; i != -1; i = edge[i].next)
            {
                int v = edge[i].v;
                if (edge[i].cap > edge[i].flow &&
                        dis[v] > dis[u] + edge[i].cost )
                {
                    dis[v] = dis[u] + edge[i].cost;
                    pre[v] = i;
                    if (!vis[v])
                    {
                        vis[v] = true;
                        q.push(v);
                    }
                }
            }
        }
        if(dis[t]>=0) return false;////////././.?
        if (pre[t] == -1)return false;
        else return true;
    }
    int minCost(int s, int t)
    {
        int flow = 0;
        int cost = 0;
        while (spfa(s, t))
        {
            int Min = inf;
            for (int i = pre[t]; i != -1; i = pre[edge[i ^ 1].v])
            {
                if (Min > edge[i].cap - edge[i].flow)
                    Min = edge[i].cap - edge[i].flow;
            }
            for (int i = pre[t]; i != -1; i = pre[edge[i ^ 1].v])
            {
                edge[i].flow += Min;
                edge[i ^ 1].flow -= Min;
                cost += edge[i].cost * Min;
            }
            flow += Min;
        }
       // cout<<cost<<"========"<<endl;
        return cost;
    }
    
    int mat[10][10] ,map1[10][10];
    int main()
    {
        int n,m,i,j,k,ans,s,e;
        int T,case1=0,cnt;
        cin >> T ;
        while(T--)
        {
            scanf("%d%d%d",&n,&m,&k) ;
            init();
            ans=cnt=0;
            for( i = 0 ;i < n ;i++)
                for( j = 0 ; j < m ;j++){
                 scanf("%d",&mat[i][j]) ;
                 ans += mat[i][j]*mat[i][j] ;
                 map1[i][j]=++cnt ;
            }
            s = 0 ;
            e = ++cnt ;
            for( i = 0 ; i < n ;i++)
                for( j = 0 ; j < m ;j++)
            {
                for( int u = 1 ; u <= k ;u++)
                {
                   if(i%2==j%2) Unit(s,map1[i][j],1,2*u-1-2*mat[i][j]) ;
                   else  Unit(map1[i][j],e,1,2*u-1-2*mat[i][j]) ;
                }
                if(i%2==j%2)
                {
                    if(i<n-1)Unit(map1[i][j],map1[i+1][j],INF,0) ;
                    if(j<m-1)Unit(map1[i][j],map1[i][j+1],INF,0) ;
                    if(i>=1)Unit(map1[i][j],map1[i-1][j],INF,0) ;
                    if(j>=1)Unit(map1[i][j],map1[i][j-1],INF,0) ;
                }
            }
            printf("Case %d: %d
    ",++case1,ans+minCost(s,e)) ;
        }
        return 0 ;
    }
    View Code

    FZU 2144 Shooting Game

    题意:有n个物体,它出现在一些地方,有一个飞行的方向,速度为1;一个人可以一次袭击把圆里面的所以物体击落

    思路:问最少多少次袭击,可以把最多的物品击落。

    联立球的方程和直线方程,可以解出 进去时间和出来时间,也就是一个居间

    这样就是用最少的点覆盖所有线段问题

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<map>
    #include<cmath>
    #include<queue>
    #include<cstring>
    #include<set>
    #include<stack>
    #include<string>
    #include<ctime>
    #define LL long long
    #define u64 unsigned long long
    #define maxn 100010
    #define mod  1000000007
    #define INF 0x3f3f3f3f
    #define eps 1e-6
    using namespace std;
    
    struct node
    {
        double L,R ;
        bool operator<(const node&s) const
        {
            return R < s.R ;
        }
    }qe[maxn] ;
    
    void getnumq(int& x){
        char ch=getchar();
        bool mk=0;
        x = 0;
        while(ch<48 || ch>57){
            if(ch=='-')    mk=1;
            ch=getchar();
        }
        while(ch>=48 && ch<=57){
            x = x*10+ch-48;
            ch = getchar();
        }
        if(mk)    x=-x;
    }
    void getnum(double& x){
        int y;
        getnumq(y);
        x = y*1.0;
    }
    int solve(int m)
    {
        sort(qe,qe+m) ;
        int ans=0,j;
        for( int i = 0 ; i < m ;i++)
        {
            ans++ ;
            j=i+1;
            while(j<m && qe[j].L <=qe[i].R )
            {
                j++ ;
            }
            i = j-1;
        }
        return ans;
    }
    int main()
    {
        int i,n,m,j,len,T,case1=0;
        double ax,ay,az,dx,dy,dz ;
        double r,a,b,c,d;
        cin >> T ;
        while(T--)
        {
            scanf("%d%lf",&n,&r) ;
            len=0;
            for( j = 1 ; j <= n ;j++ )
            {
                getnum(ax); getnum(ay); getnum(az);
                getnum(dx); getnum(dy); getnum(dz);
                a = dx*dx+dy*dy+dz*dz;
                b = 2*(ax*dx+ay*dy+az*dz);
                c = ax*ax+ay*ay+az*az-r*r;
                d = b*b-4*a*c;
                if(d<0)continue;
                qe[len].L = (b*(-1)-sqrt(d))/(a*2);
                qe[len].R = (b*(-1)+sqrt(d))/(a*2);
                if(qe[len].L<0 && qe[len].R<0)continue;
                len++;
            }
            printf("Case %d: %d %d
    ",++case1,len,solve(len)) ;
        }
        return 0 ;
    }
    View Code

    FZU 2148 Moon Game

    题意:给出n个点,问组成凸四边形的组数

    思路:数据很小,枚举。然后判断是否是凸的,

    判断大概可以用凸包了......

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<map>
    #include<cmath>
    #include<queue>
    #include<cstring>
    #include<set>
    #include<stack>
    #include<string>
    #include<ctime>
    #define LL long long
    #define maxn 50
    #define MAX 700010
    #define mod  1000000007
    #define INF 0x3f3f3f3f
    #define eps 1e-6
    using namespace std;
    
    struct point
    {
        int x , y ;
        point(){};
        point( int xx , int yy )
        {
            x = xx ; y = yy ;
        }
    } ;
    point qe[maxn] , p[maxn] ;
    point operator - ( point a , point b )
    {
        return point( b.x-a.x , b.y-a.y ) ;
    }
    int cross( point a  , point b )
    {
        return a.x*b.y - a.y*b.x ;
    }
    
    int cmp( point a , point b )
    {
        return a.y < b.y || a.y == b.y && a.x < b.x ;
    }
    int Get( int n )
    {
        sort(qe,qe+n,cmp) ;
        int m = 1 , i , k;
        if( n == 0 ) return 0 ;p[0] = qe[0] ;
        if( n == 1 ) return 1 ;p[1] = qe[1] ;
        if( n == 2 ) return 2 ;p[2] = qe[2] ;
        for( i = 2 ; i < n ;i++)
        {
            while( m && cross( p[m]-p[m-1] , qe[i] - p[m-1] ) <= 0 )m-- ;
            p[++m] = qe[i] ;
        }
        k = m ;p[++m] = qe[n-2] ;
        for( i = n-3 ; i >= 0 ; i-- )
        {
            while( m > k && cross( p[m]-p[m-1] , qe[i]-p[m-1] ) <= 0 )m-- ;
            p[++m] = qe[i] ;
        }
        return m ;
    }
    int xx[maxn],yy[maxn] ;
    int main()
    {
        int T,case1=0,n ;
        int i,j,k,u,v,ans;
        cin >> T ;
        while(T--)
        {
             scanf("%d",&n) ;
             for( i = 1 ; i <= n ;i++)
                scanf("%d%d",&xx[i],&yy[i]) ;
             ans=0;
             for( i=1 ; i<= n ;i++)
               for(j=i+1;j<=n;j++)
                 for(u=j+1;u<=n;u++)
                  for(v=u+1;v<=n;v++)
             {
                 qe[0].x=xx[i] ;qe[0].y=yy[i] ;
                 qe[1].x=xx[j] ;qe[1].y=yy[j] ;
                 qe[2].x=xx[u] ;qe[2].y=yy[u] ;
                 qe[3].x=xx[v] ;qe[3].y=yy[v] ;
                 k = Get(4) ;
                 //cout<<k<<endl;
                 if(k==4)ans++;
             }
             printf("Case %d: %d
    ",++case1,ans) ;
        }
        return 0;
    }
    View Code

    FZU 2150 Fire Game

    题意:、

    思路:枚举两点,然后dfs;

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<map>
    #include<cmath>
    #include<queue>
    #include<cstring>
    #include<set>
    #include<stack>
    #include<string>
    #include<ctime>
    #define LL long long
    #define maxn 20
    #define MAX 700010
    #define mod  1000000007
    #define INF 0x3f3f3f3f
    #define eps 1e-6
    using namespace std;
    
    char mat[maxn][maxn] ;
    int time1[maxn][maxn] ;
    int n,m;
    
    void dfs(int x,int y,int t)
    {
        time1[x][y]= t ;
        if(x>1&&mat[x-1][y]=='#'&&time1[x-1][y]>t+1)
        {
            dfs(x-1,y,t+1);
        }
        if(y>1&&mat[x][y-1]=='#'&&time1[x][y-1]>t+1)
        {
            dfs(x,y-1,t+1);
        }
        if(x<n&&mat[x+1][y]=='#'&&time1[x+1][y]>t+1)
        {
            dfs(x+1,y,t+1);
        }
        if(y<m&&mat[x][y+1]=='#'&&time1[x][y+1]>t+1)
        {
            dfs(x,y+1,t+1);
        }
    }
    int solve(int s1,int e1,int s2,int e2)
    {
    
        memset(time1,INF,sizeof(time1)) ;
        dfs(s1,e1,0) ;
        dfs(s2,e2,0) ;
        int ans=-1 ;
        for(int i = 1 ; i <= n ;i++)
            for(int j = 1 ; j <= m ;j++)if(mat[i][j]=='#')
            {
                ans=max(ans,time1[i][j]) ;
            }
            return ans;
    }
    
    int getans()
    {
        int ans=INF,t;
        for(int i = 1 ; i <= n ;i++)
            for(int j = 1 ; j <= m ;j++)if(mat[i][j]=='#')
        {
            for(int k = i ; k <= n ;k++)
                for(int kk = 1 ; kk <= m ;kk++)if(mat[k][kk]=='#')
            {
                int t = solve(i,j,k,kk) ;
                if(t==-1) t = INF ;
                ans=min(ans,t) ;
            }
        }
        if(ans==INF) return -1;
        return ans;
    }
    
    int main()
    {
        int T,case1=0 ;
        int i,j,k,ans;
        cin >> T ;
        while(T--)
        {
             scanf("%d%d",&n,&m) ;
             for( i = 1 ; i <= n ;i++)
                scanf("%s",mat[i]+1) ;
             printf("Case %d: %d
    ",++case1,getans()) ;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    logback-spring.xml配置文件详解
    SpringBoot-Controller接收参数的几种常用方式
    spring boot配置定时任务设置
    SpringCloud 配置文件 application.yml和 bootstrap.yml区别
    ajax/get请求
    ajax封装2
    ajax封装1
    楼层特效
    旋转动画
    联动动画
  • 原文地址:https://www.cnblogs.com/20120125llcai/p/4343184.html
Copyright © 2011-2022 走看看