題目出自:廈門大學OJ的1046
這題嘛,出的還是比較好的。
遊戲中實現的尋路演算法,可能是astar或者dj
但題目裡這麼問起來,那就不能用常規的尋路演算法了。畢竟一個是方框,另一個園。方框可以看成座標系的點,但是圓不行。所以還是要用計算幾何。
開始的思路是:
1.先判斷英雄座標是否在點組成的多邊形內;
2.再判斷把點按逆時針的順序連起來,按順序計算每兩個點之間的距離是否大於圓的直徑和兩個點的半徑(limit)。
後來發現這個演算法有很大的缺陷,無法計算凹多邊形。
糾正的思路是:
1.先計算可以阻塞英雄的邊(兩個點距離小於limit),把這些點存到一個上三角矩陣裡;
2.由上面的矩陣構成一個鄰接表;
3.找出鄰接表中各個點作為起點存在的迴路;
4.判斷英雄座標是否在迴路中。
代碼可以再精簡點。不過懶得弄了。。。呵呵
#include<stdio.h>#include<stdlib.h>#include <math.h>int fp=0;int hero[3];int unit[20][4];int matrix[100][100];double culcos(int x,int y,int xo,int yo,int n,int m){double s;s=sqrt((x-n)*(x-n)+(y-m)*(y-m))*sqrt((xo-n)*(xo-n)+(yo-m)*(yo-m));return acos(((x-n)*(xo-n)+(y-m)*(yo-m))/s);}struct node {int val;struct node* next;};struct node *nnode[20];struct path{int dep;int nnum[20];};struct path wpath;int stackInit(){int i;wpath.dep=0;for(i=0;i<20;i++){wpath.nnum[i]=-1;}return 0;}static void stackPush(int val){wpath.nnum[wpath.dep]=val;wpath.dep++;return;}static void stackPull(){wpath.dep--;wpath.nnum[wpath.dep]=-1;}static int stackTop(){return wpath.nnum[wpath.dep-1];}static int stackIn(int val){int j;for(j=0;j<wpath.dep;j++){if(wpath.nnum[j]==val){return 1;}}return 0;}static int stackBottom(){return wpath.nnum[0];}static void stackShow(){int j;printf("stack dep %d:\n",wpath.dep);for(j=0;j<wpath.dep;j++){printf("%d ",wpath.nnum[j]);}printf("\n");return ;}int walkPath(){int n,s;n=stackTop();s=stackBottom();if(nnode[n]->next==NULL){return 0;}struct node * next;next=nnode[n]->next;while(next!=NULL){if(next->val==s&&wpath.dep>2){int a[20][4];int k;for(k=0;k<wpath.dep;k++){a[k][0]=unit[wpath.nnum[k]][0];a[k][1]=unit[wpath.nnum[k]][1];a[k][2]=unit[wpath.nnum[k]][2];}int ret;ret=isin(a,wpath.dep,hero);if(ret==1)fp++;return 2;}if(next->val==s){next=next->next;continue;}if(stackIn(next->val)){next=next->next;continue;}stackPush(next->val);walkPath();stackPull();if(next->next==NULL)break;next=next->next;}return 0;}static int findPath(int num){int i;for(i=0;i<num;i++){stackInit();if(nnode[i]->next!=NULL){stackPush(i);walkPath();}else{}}return 0;}int isin(int a[][4],int num,int b[]){int i=0;double sigma=0.0;for(i=0;i<num;i++){int j=(i+1)%num;sigma+=culcos(a[i][0],a[i][1],a[j][0],a[j][1],b[0],b[1]);}if(abs(sigma-2*3.14159)<0.00001)return 1;else{for(i=0;i<num;i++){}return 0;}}int swap(int *a,int *b){int t;if(a==NULL||b==NULL){printf("swap error\n");return 0;}t=*a;*a=*b;*b=t;return 1;}int bubbleEdge(int a[][4],int num){int i,j;for(i=num-1;i>0;i--){for(j=0;j<i;j++){if(a[j][0]>a[j+1][0]){swap(&a[j][0],&a[j+1][0]);swap(&a[j][1],&a[j+1][1]);swap(&a[j][2],&a[j+1][2]);}}}return 0;}int main(){int num;scanf("%d",&num);int i;for(i=0;i<num;i++){scanf("%d%d%d",&unit[i][0],&unit[i][1],&unit[i][2]);}scanf("%d%d%d",&hero[0],&hero[1],&hero[2]);int j;double dist,limit;bubbleEdge(unit,num);for(i=0;i<num;i++){for(j=0;j<num;j++){if(i==j)continue;dist=sqrt((unit[i][0]-unit[j][0])*(unit[i][0]-unit[j][0])+(unit[i][1]-unit[j][1])*(unit[i][1]-unit[j][1]));limit=unit[i][2]+unit[j][2]+2*hero[2];if(dist<limit)matrix[i][j]=1;}}for(i=0;i<num;i++){nnode[i]=(struct node*)malloc(sizeof(struct node));nnode[i]->val=i;struct node* ne;struct node* next; for(j=0;j<num;j++){next=nnode[i];if(matrix[i][j]==1){ne=(struct node*)malloc(sizeof(struct node));ne->val=j;while(next->next!=NULL){next=next->next;}next->next=ne;}}}findPath(num);if(fp>0)printf("Yes\n");elseprintf("No\n");return 0;}