zoukankan      html  css  js  c++  java
  • LETTers练习赛十一场解题报告

    第1题解题报告

    提交人:蔡驰宇

    提交日期:2012.05.09

    题目描述

    很水的一道题,实际上就是一个三角形求重心的问题,套用公式就好了。

    程序

    #include<iostream>

    #include<cmath>

    using namespace std;

    const int inf=1<<29;

    const int M=50200;

    const double eps=1e-8;

    struct point

    {

        double x,y;

    }po[5],p,g;

    int n;

    int main()

    {

        int T,i;

        while(scanf("%d",&T)==1)

        {

            if(!T) break;

            while(T--)

            {

                for(int i=0;i<3;i++)

                    scanf("%lf%lf",&po[i].x,&po[i].y);

                double tp,area=0,tpx=0,tpy=0;

                p.x=po[0].x;

                p.y=po[0].y;

                for(i=1;i<=3;i++)

                {

                    g.x=po[(i==3)?0:i].x;

                    g.y=po[(i==3)?0:i].y;

                    tp=(p.x*g.y-p.y*g.x);

                    area+=tp/2;

                    tpx=tpx+(p.x+g.x)*tp;

                    tpy=tpy+(p.y+g.y)*tp;

                    p.x=g.x;

                    p.y=g.y;

                }

                g.x=tpx/(6*area);

                g.y=tpy/(6*area);

                printf("%.1lf %.1lf\n",g.x,g.y);

            }

        }

        return 0;

    }

    第2题解题报告

    题目描述

    一个二分法的题目,原理并不难,但是在计算时要注意精度,High和Low判断相等的过程中精度要达到10^-9以上才能AC。

    程序

    #include <iostream>

    #include <cmath>

    using namespace std;

    #define N 10005

    #define EPS 1e-10

    double elem[N];

    int n,m;

    int judge(double x)

    {

           int i;

           int count=0;

           for(i=0;i<n;i++)

           {

                  count+=(int)(elem[i]/x);

           }

           if(count>=m)

                  return 1;

           else return 0;

    }

    int main()

    {

           int i;

           double MAX=0,low,high,mid;

           while(scanf("%d%d",&n,&m),m+n)

           {

                  for(i=0;i<n;i++)

                  {

                         scanf("%lf",&elem[i]);

                         MAX+=elem[i];

                  }

                  MAX/=m;

                  low=0;

                  high=MAX;

                  while(fabs(low-high)>EPS)

                  {

                         mid=(low+high)/2;

                         if(judge(mid)==1)

                                low=mid;

                         else

                                high=mid;

                  }

                  printf("%.2lf/n",low);

           }

           return 0;

    }

    第3题解题报告

    题目描述

    一个较为典型的母函数应用,由题意可知,相同的硬币可以重复,那就为可重复组合。

    构造函数G(x)=(1+x+x^2+…)(1+x^4+x^8+…)…(1+x^289+x^578+…)。

    程序

    #include<stdio.h>

    #include<string.h>

    #define MAXD 20

    #define MAXM 310

    int f[MAXD][MAXM], N;

    void prepare()

    {

        int i, j, k;

        memset(f, 0, sizeof(f));

        f[0][0] = 1;

        for(i = 1; i <= 17; i ++)

            for(j = 0; j <= 300; j += i * i)

                for(k = 0; k + j <= 300; k ++)

                    f[i][k + j] += f[i - 1][k];

    }

    int main()

    {

        prepare();

        for(;;)

        {

            scanf("%d", &N);

            if(!N)

                break;

            printf("%d\n", f[17][N]);

        }

        return 0;

    }

    第4题解题报告

    题目描述

    封锁出口或者入口周围的格子.

    最多需要4个封锁点.

    所以我们可以采取这样的策略:

    1.寻找一条盗贼的可行路线,如果没有,返回0.

    2.计算封锁出口和入口四周需要的封锁点数量,取小的一个,假设是k,k <=4

    3.从少到多,遍历所有封锁点个数小于k的方案,验证是否是一条有效的覆盖方案

    (可以通过是否阻止了1中的盗贼线路进行快速验证).

    如果有有效覆盖方案,返回这个方案的覆盖点值,否则继续.

    4.如果没有比k小的覆盖方案,返回k.

    时间复杂度:

    最多(M*N)^3次有效覆盖验证.即(8*8)^3=256k次.其中有很大一部分可以通过快速验证排除(取决于1的路径长短,所以一般1应该求出最短路径的可行路线)

    程序

    #include <iostream>

    #include <queue>

    #include <string>

    using namespace std;

    int n,m,t,ans;

    int dir[4][2] = {1,0,-1,0,0,-1,0,1};

    char map[10][10];

    bool vis[2][10][10];

    struct node

    {

        int x,y,t,k;//x,y为坐标,t为时间,k为是否有碰到宝石

        int rox[64],roy[64];//用来保存路径的,每个节点都保存有一条路径,只有到达终点后才有完整的路径

    };

    node start,end,temp,in;

    queue <node> Q;

    void dfs(int deep)

    {

        if(deep > ans) return ;

        int i,j,minstep = -1;

        node q;

        while(!Q.empty())//清空队列

            Q.pop();

        Q.push(start);//起始位置入队

        memset(vis,false,sizeof(vis));//初始化标记数组

        vis[0][start.x][start.y] = true;//标记起始点为真

        while(!Q.empty())//从起点开始寻找一条路径

        {

            q = Q.front();

            Q.pop();

            if(q.t > t)

                continue;

            if(q.k && map[q.x][q.y] == 'E')//找到出口

            {

                minstep = q.t;

                break;

            }

            for(i = 0;i < 4;i++)//分别从四个方向开始扫描

            {

                int xx = q.x + dir[i][0];

                int yy = q.y + dir[i][1];

                if(xx < 0 || xx >= n || yy < 0 || yy >= m || map[xx][yy] == '#')

                    continue;//越界或碰到墙

                if(map[xx][yy] == 'J')

                    in.k = 1;//碰到珠宝

                else

                    in.k = q.k;//没有碰到则标记为前一个状态

                if(!vis[in.k][xx][yy])

                {

                    vis[in.k][xx][yy] = true;

                    for(j = 1;j <= q.t;j++) //将前一节点保存的路径加入到现在的节点,由于是按顺序的,所以他会形成连贯的路线

                    {

                        in.rox[j] = q.rox[j];

                        in.roy[j] = q.roy[j];

                    }

                    in.x = xx;

                    in.y = yy;

                    in.t = q.t + 1;

                    //这个节点的第in.t步保存的是xx,yy

                    in.rox[in.t] = xx;

                    in.roy[in.t] = yy;

                    Q.push(in);

                }

            }

        }

        if(minstep == -1)

        {// minstep == -1 表明在t时间内即使不用设置关卡也不能成功逃离

            if(deep < ans)

                ans = deep;

            return ;

        }

        char cc;

        for(i = 1;i < q.t;i++)

        {

            cc = map[q.rox[i]][q.roy[i]];

            if(cc == 'S' || cc == 'E')

                continue;

            map[q.rox[i]][q.roy[i]] = '#';//在做完前面的bfs后,这里的q是到达终点的节点,因此他完整的保存了一条路

            dfs(deep+1);

            map[q.rox[i]][q.roy[i]] = cc ;

        }

    }

    void inits()

    {

        int i,j;

        memset(vis,false,sizeof(vis));

        for(i = 0;i < n;i++)

            for(j = 0;j < m;j++)

            {

                if(map[i][j] == 'S')

                {

                    start.x = i;start.y = j;

                    start.t = 0;start.k = 0;

                    break;

                }

            }

            ans = 4;

            dfs(0);

            printf("%d\n",ans);

    }

    int main()

    {

        int i,cas;

        scanf("%d",&cas);

        while(cas--)

        {

            scanf("%d%d%d",&n,&m,&t);

            for(i = 0;i < n;i++)

                scanf("%s",map[i]);

            inits();

        }

        return 0;

    }

  • 相关阅读:
    "std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::str() const"
    Incompatible integer to pointer conversion sending 'NSInteger' (aka 'int') to parameter of type 'id'
    App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app’s Info.plist file
    Bitmasking for introspection of Objective-C object pointers i
    Bitmasking for introspection of Objective-C object pointers
    iOS中常见的报错及解决方案
    Swift3.1
    iOS9使用提示框的正确实现方式(UIAlertView is deprecated)
    IOS8 PUSH解决方法
    栈溢出实践
  • 原文地址:https://www.cnblogs.com/LETTers/p/2492661.html
Copyright © 2011-2022 走看看