杭电 1006 1007 1010

        最近做的比较有意思的编程题吧。

Tick Tick(杭电1006)

      题的难点在求合集的问题,还是很有意思。

1、求出六段的交集。

2、将这些集合的分割点排序。

3、循环判断,两两分割点形成的区域是否在六段集合中,在任意一个集合,计数器加一。

4、检查两两分割点构成的区间,是否有计数器在6以上的。表明该区间至少满足了六个公式。


tips:这个方法很不错。提示的是,在第三步中,|a - x | < m 计算的结果是 s1  < x < s2这样的集合。反之却是x > s1或者 x < s2,分成两拨来计算,具体可以参考代码。

     贴下代码吧。见下文中HappyTime 函数。

Quoit Design (1007)

     最近点问题。算法导论计算几何学第二版的,在611页。。。可以仔细看看。

1、得到数据后,按Y排序。

2、分治。得到最小值a。递归吧。。。

3、合并,最近点可能跨域左右两部分。找到中间线a范围的点。然后按X排序,找点的距离最小值是否小于a的。


tips:1、要想做的再好点。可以对点做个数据结构,分左右两点算,以便第三步计算的点能少很多的。

      2、重点是,先对Y排序,然后排序X。数据问题的说。。。

      有代码的哟。亲。

Template of Bone(1010):

   深度优先搜索,递归或者栈。时间性呢。好像不是太好。。欢迎提出高级想法。

1、检查立刻返回点条件。

2、循环,标记下一个点

3、递归。判断返回结果,如果找到了返回1,反之进入步骤4

4、取消标记。

   代码的话。下面贴了。跟大家的大同小异吧。

1006:(部分)
double HappyTime(int h,int m,int a){
    double sum;
    double temp[3],p[3],n[3];
    double num[14];
    double local[12];
    int map[13];
    int i;
    sum=0;
    temp[0] = 30*h-5.5*m;
    temp[1] = 30*h+0.5*m;
    temp[2] = 6*m;
    p[0]=11;p[1]=719;p[2]=59;
    n[0]=n[1]=120,n[2]=10;
    num[0]=0;num[1]=60;
    for(i=0;i<3;i++)
    {
        double l1,l2;
        double r1,r2;
        l1 = (temp[i]-a)*n[i]/p[i];
        l2 = (a+temp[i])*n[i]/p[i];
        r1=(temp[i]+a-360)*n[i]/p[i];
        r2=(360+temp[i]-a)*n[i]/p[i];
        int pt =i*4;
        num[pt+2]=local[pt]=l2;
        num[pt+3]=local[pt+1]=l1;
        num[pt+4]=local[pt+2]=r1;
        num[pt+5]=local[pt+3]=r2;
    }
    qsort(num,14,sizeof(num[0]),cmp);//排序 qsort排序很方便
    memset(map,0,sizeof(map));
    for(i=0;i<3;i++)
    {
        int tempa,tempb;
        tempa=GetwhereD(num,map,local[4*i],local[4*i+1]);//上文提到的x大于小于的问题   
        tempb=GetwhereX(num,map,local[4*i+2],local[4*i+3]);
        if(!tempa&&!tempb)return 0;//提高下速度,如果两个方程都不满足,后续也就不用算了。
    }
    for(i=0;i<13;i++)
    {
        if(map[i]==6)
        {    
            sum += num[i+1]-num[i];
        }
    }
    return sum;
}


1007(部分):
double Min(int start ,int end){
    if(start==end){
        return 99999999;
    }
    else if(end==start +1){
        return Distance(P[start],P[end]);    
    }
    else if (end==start+2){
        double s12 = Distance(P[start],P[start+1]);
        double s23 = Distance(P[start+1],P[end]);
        double s13 = Distance(P[start],P[end]);
        return getm(getm(s12,s23),s13);
    }
    else{
        int mid = (start+end)/2    ;
        double q = Min(start, mid);
        double h = Min(mid+1,end);
        double F_Max = getm(q,h);
        int i ,j,k;    
        for(i =start,k=0;i<=end;i++)
        {
            if(fabs(P[i].y-P[mid].y)<F_Max){
                L[k]= P[i];
                k++;
            }
        }
        qsort(L,k,sizeof(struct Point),cmp_X);
        for(i=0;i<k-1;i++)
        {
            for(j=i+1;j<i+8&&j<k;j++)
            {
                if(fabs(L[j].x-L[i].x)>=F_Max)
                {
                    break;
                }
                else
                {
                    double temp = Distance(L[i],L[j]);
                    F_Max = getm(F_Max,temp);
                }
            }
        }
        return F_Max;
    }
    return 0;
}

1010:(部分)
const int move[4][2]={{0,-1},{0,1},{-1,0},{1,0}}; 
char maze[9][9];
int door_i,door_j;
int IsEscape(int dog_i,int dog_j,int time){
    if(dog_i==door_i&&dog_j==door_j&&time==0)
        return 1;
    else{
        int i;
        if(abs(dog_i-door_i)+abs(dog_j-door_j)>time)return 0;
        for(i=0;i<4;i++)
        {
            int next_i = dog_i +  move[i][0];
            int next_j = dog_j +  move[i][1];
            if(maze[next_i][next_j]!='X' && time)
            {
                maze[next_i][next_j]='X'; 
                if(IsEscape(next_i,next_j,time-1))return 1;
                else maze[next_i][next_j]='.';
            }
        }
        return 0;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值