判斷圓是否被若干圓包圍的問題–廈大1046

來源:互聯網
上載者:User

題目出自:廈門大學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;}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.