最近做的比较有意思的编程题吧。
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; } }