ECUST 09年 校赛个人训练赛第五场总结

今天战绩还行,AC了5题,今天总体没有太复杂的算法题,不过测试数据强度比之前有所增加 我的钱四题很早就过了,但是第五题很晚才出主要是代码写得太混乱,思路也错了两次 我过的题有五道,分别是ABCDG

A Coming Near

A题是计算两个多边形的最近距离

由于数据量不是很大,所以O(n^2)的算法就能过,也就是枚举,每一个用例的最坏情况是310001000

具体是先枚举每两个点的距离,记录最小值

再枚举每个点到另一个多边形上每条直线的距离,记录最小值即可

不过lpld的因为越界导致的WA问题值得借鉴(及时把long型转为double型)

#include<iostream>
#include<cmath>
using namespace std;
struct vertex
{
    long x,y;
};

vertex prisonA[1000],prisonB[1000];

double disBetweenAB(int posA,int posB)
{
    double tmp1 = prisonA[posA].x - prisonB[posB].x;
    double tmp2 = prisonA[posA].y - prisonB[posB].y;
    return sqrt(tmp1 * tmp1 + tmp2 * tmp2);
}
double disBetweenPointAndLine(long x0,long y0,long x1,long y1,long x2,long y2)
{
    double a = y1-y2;
    double b = x2-x1;
    double c = x1*y2-x2*y1;
    double d = (a*x0+b*y0+c)/sqrt(a*a+b*b);
    double xp = (b*b*x0-a*b*y0-a*c)/(a*a+b*b);
    double yp = (-a*b*x0+a*a*y0-b*c)/(a*a+b*b);
    double xb = (x1>x2)?x1:x2;
    double yb = (y1>y2)?y1:y2;
    double xs = x1+x2-xb;
    double ys = y1+y2-yb;
    if(xp > xb || xp < xs || yp > yb || yp < ys)
        return 50000000;
    else
        return fabs(d);
}

int main()
{
    int m,n;
    while(scanf("%d %d",&n,&m),n || m)
    {
        int i,j;
        for(i = 0 ; i < n ; i ++)
            scanf("%ld %ld",&prisonA[i].x,&prisonA[i].y);
        for(i = 0 ; i < m ; i ++)
            scanf("%ld %ld",&prisonB[i].x,&prisonB[i].y);
        double tmpDouble = disBetweenAB(0,0);
        for(i = 0 ; i < n ; i ++)
            for(j = 0 ; j < m ; j ++)
                if(disBetweenAB(i,j) < tmpDouble)
                    tmpDouble = disBetweenAB(i,j);
        for(i = 0 ; i < n ; i ++)
            for(j = 0 ; j < m ; j ++)
            {
                double tmpDouble2 = disBetweenPointAndLine(prisonA[i].x,prisonA[i].y
                    ,prisonB[j].x,prisonB[j].y,prisonB[(j+1)%m].x,prisonB[(j+1)%m].y);
                if(tmpDouble2 < tmpDouble)
                    tmpDouble = tmpDouble2;
            };

        for(i = 0 ; i < m ; i ++)
            for(j = 0 ; j < n ; j ++)
            {
                double tmpDouble2 = disBetweenPointAndLine(prisonB[i].x,prisonB[i].y
                    ,prisonA[j].x,prisonA[j].y,prisonA[(j+1)%n].x,prisonA[(j+1)%n].y);
                if(tmpDouble2 < tmpDouble)
                    tmpDouble = tmpDouble2;
            };

        printf("%.2lf\n",tmpDouble);
    }
    return 0;
}

B Love Letter

B题是要求重新排列单词,使之成为字典里的单词,以此读懂别人打乱加密的Love Letter

这题很简单,直接一个一个单词查找就行了,不过要注意一下换行的位置,因为题目要求输出和输入一样

继续贴代码:

C Change Base

C题是一道进制转换题,稍微思考一下就能推出公式了,然后每次处理mod一个10007就行

(注: a % c + b % c = ( a + b ) % c ( a b ) % c = ( a % c b % c ) % c )

代码:

D Equation

D题要用Hash的思想,但是因为是long型的数据而且数据量不大(1000*1000),可以不写哈希函数,直接映射

我的代码如下:

G Fermat square prime

G题是计算能用a^2+b^2表示的素数(a,b为素数)

我的大体思路是先筛出素数表,再把素数依次组合,算出所有能这么表示的数

最后再读入数据,判断读入的数据是否是能以a^2+b^2的素数

代码如下:

这次总体感觉前期不错,后期就一直卡住了,想到的算法错误浪费了我很多时间 最后一题的思路错误导致一直WA,以后需要注意,思路清晰很重要。

Last updated

Was this helpful?