Friend Chains http://acm.hdu.edu.cn/showproblem.php?pid=4460
图的最远两点距离,任意选个点bfs,如果有不能到的点直接-1.然后对于所有距离最远的点都bfs一次。最坏n^2
邻接表
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<queue> 5 #include<map> 6 #define mt(a,b) memset(a,b,sizeof(a)) 7 using namespace std; 8 const int M=1024; 9 char a[16],b[16]; 10 map<string,int> name; 11 struct G{ 12 struct E{ 13 int v,next; 14 }e[M*20]; 15 int le,head[M]; 16 void init(){ 17 le=0; 18 mt(head,-1); 19 } 20 void add(int u,int v){ 21 e[le].v=v; 22 e[le].next=head[u]; 23 head[u]=le++; 24 } 25 }g; 26 int dist[M],id[M]; 27 bool vis[M]; 28 queue<int> q; 29 void bfs(int s){ 30 mt(vis,0); 31 mt(dist,-1); 32 vis[s]=true; 33 dist[s]=0; 34 while(!q.empty()) q.pop(); 35 q.push(s); 36 while(!q.empty()){ 37 int u=q.front(); 38 q.pop(); 39 for(int i=g.head[u];~i;i=g.e[i].next){ 40 int v=g.e[i].v; 41 if(!vis[v]){ 42 vis[v]=true; 43 dist[v]=dist[u]+1; 44 q.push(v); 45 } 46 } 47 } 48 } 49 int main(){ 50 int n,m; 51 while(~scanf("%d",&n),n){ 52 name.clear(); 53 for(int i=0;i<n;i++){ 54 scanf("%s",a); 55 name[(string)a]=i; 56 } 57 scanf("%d",&m); 58 g.init(); 59 while(m--){ 60 scanf("%s%s",a,b); 61 int u=name[(string)a]; 62 int v=name[(string)b]; 63 g.add(u,v); 64 g.add(v,u); 65 } 66 bfs(0); 67 bool flag=false; 68 for(int i=0;i<n;i++){ 69 if(dist[i]==-1){ 70 flag=true; 71 break; 72 } 73 } 74 if(flag){ 75 puts("-1"); 76 continue; 77 } 78 int big=0; 79 for(int i=0;i<n;i++){ 80 big=max(big,dist[i]); 81 } 82 int ld=0; 83 for(int i=0;i<n;i++){ 84 if(dist[i]==big){ 85 id[ld++]=i; 86 } 87 } 88 int ans=0; 89 for(int i=0;i<ld;i++){ 90 bfs(id[i]); 91 for(int j=0;j<n;j++){ 92 ans=max(ans,dist[j]); 93 } 94 } 95 printf("%d ",ans); 96 } 97 return 0; 98 }
vector竟然还快些
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<queue> 5 #include<map> 6 #define mt(a,b) memset(a,b,sizeof(a)) 7 using namespace std; 8 const int M=1024; 9 char a[16],b[16]; 10 map<string,int> name; 11 vector<int> g[M]; 12 int dist[M],id[M]; 13 bool vis[M]; 14 queue<int> q; 15 void bfs(int s){ 16 mt(vis,0); 17 mt(dist,-1); 18 vis[s]=true; 19 dist[s]=0; 20 while(!q.empty()) q.pop(); 21 q.push(s); 22 while(!q.empty()){ 23 int u=q.front(); 24 q.pop(); 25 int len=g[u].size(); 26 for(int i=0;i<len;i++){ 27 int v=g[u][i]; 28 if(!vis[v]){ 29 vis[v]=true; 30 dist[v]=dist[u]+1; 31 q.push(v); 32 } 33 } 34 } 35 } 36 int main(){ 37 int n,m; 38 while(~scanf("%d",&n),n){ 39 name.clear(); 40 for(int i=0;i<n;i++){ 41 scanf("%s",a); 42 name[(string)a]=i; 43 g[i].clear(); 44 } 45 scanf("%d",&m); 46 while(m--){ 47 scanf("%s%s",a,b); 48 int u=name[(string)a]; 49 int v=name[(string)b]; 50 g[u].push_back(v); 51 g[v].push_back(u); 52 } 53 bfs(0); 54 bool flag=false; 55 for(int i=0;i<n;i++){ 56 if(dist[i]==-1){ 57 flag=true; 58 break; 59 } 60 } 61 if(flag){ 62 puts("-1"); 63 continue; 64 } 65 int big=0; 66 for(int i=0;i<n;i++){ 67 big=max(big,dist[i]); 68 } 69 int ld=0; 70 for(int i=0;i<n;i++){ 71 if(dist[i]==big){ 72 id[ld++]=i; 73 } 74 } 75 int ans=0; 76 for(int i=0;i<ld;i++){ 77 bfs(id[i]); 78 for(int j=0;j<n;j++){ 79 ans=max(ans,dist[j]); 80 } 81 } 82 printf("%d ",ans); 83 } 84 return 0; 85 }
The Power of Xiangqi http://acm.hdu.edu.cn/showproblem.php?pid=4461
o(n)水题。每个旗子有权值,算一算权值比一比。注意至少1分。如果b和c有一个没有就扣一分。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 using namespace std; 6 const int M=16; 7 int sa[M],sb[M]; 8 int val[]={16,7,8,1,1,2,3}; 9 int main(){ 10 int t,n; 11 char op[4]; 12 while(~scanf("%d",&t)){ 13 while(t--){ 14 mt(sa,0); 15 mt(sb,0); 16 scanf("%d",&n); 17 while(n--){ 18 scanf("%s",op); 19 sa[op[0]-'A']++; 20 } 21 scanf("%d",&n); 22 while(n--){ 23 scanf("%s",op); 24 sb[op[0]-'A']++; 25 } 26 int suma=0,sumb=0; 27 for(int i=0;i<7;i++){ 28 suma+=val[i]*sa[i]; 29 sumb+=val[i]*sb[i]; 30 } 31 if(!sa[1]||!sa[2]) suma--; 32 if(!sb[1]||!sb[2]) sumb--; 33 suma=max(1,suma); 34 sumb=max(1,sumb); 35 if(suma>sumb){ 36 puts("red"); 37 } 38 else if(suma<sumb){ 39 puts("black"); 40 } 41 else{ 42 puts("tie"); 43 } 44 } 45 } 46 return 0; 47 }
Scaring the Birds http://acm.hdu.edu.cn/showproblem.php?pid=4462
二进制枚举放的情况,判断能否覆盖所有的玉米,注意能放的地方已经没有玉米了,不用判这个点。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 using namespace std; 6 const int inf=0x3f3f3f3f; 7 const int M=64; 8 bool mat[M][M]; 9 struct G{ 10 int x,y,r; 11 }p[16]; 12 int one(int x){ 13 int res=0; 14 while(x){ 15 if(x&1) res++; 16 x>>=1; 17 } 18 return res; 19 } 20 int used[16]; 21 int main(){ 22 int n,m; 23 while(~scanf("%d",&n),n){ 24 scanf("%d",&m); 25 mt(mat,0); 26 for(int i=0;i<m;i++){ 27 scanf("%d%d",&p[i].x,&p[i].y); 28 mat[p[i].x][p[i].y]=true; 29 } 30 for(int i=0;i<m;i++){ 31 scanf("%d",&p[i].r); 32 } 33 int all=1<<m; 34 int ans=inf; 35 for(int i=0;i<all;i++){ 36 int now=one(i); 37 if(now>=ans) continue; 38 int lu=0; 39 for(int j=0;j<m;j++){ 40 if((i>>j)&1){ 41 used[lu++]=j; 42 } 43 } 44 bool flag=true; 45 for(int x=1;x<=n;x++){ 46 for(int y=1;y<=n;y++){ 47 if(mat[x][y]) continue; 48 bool ok=false; 49 for(int j=0;j<lu;j++){ 50 int id=used[j]; 51 if(abs(x-p[id].x)+abs(y-p[id].y)<=p[id].r){ 52 ok=true; 53 break; 54 } 55 } 56 if(!ok){ 57 flag=false; 58 break; 59 } 60 } 61 if(!flag) break; 62 } 63 if(flag){ 64 ans=min(ans,now); 65 } 66 } 67 if(ans==inf) ans=-1; 68 printf("%d ",ans); 69 } 70 return 0; 71 }
Outlets http://acm.hdu.edu.cn/showproblem.php?pid=4463
最小生成树,必须有一条边先加进去,那就加个权值为零的,然后ans直接加上边权,这样就保证一定有这个边了。
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 #define mt(a,b) memset(a,b,sizeof(a)) 6 using namespace std; 7 const int M=64; 8 class Kruskal { ///最小生成树(无向图)o(ME*logME) 9 typedef double typec;///边权的类型 10 static const int ME=M*M;///边的个数 11 static const int MV=M;///点的个数 12 class UnionFindSet { ///并查集 13 int par[MV]; 14 public: 15 void init() { 16 mt(par,-1); 17 } 18 int getroot(int x) { 19 int i=x,j=x,temp; 20 while(par[i]>=0) i=par[i]; 21 while(j!=i) { 22 temp=par[j]; 23 par[j]=i; 24 j=temp; 25 } 26 return i; 27 } 28 bool unite(int x,int y) { 29 int p=getroot(x); 30 int q=getroot(y); 31 if(p==q)return false; 32 if(par[p]>par[q]) { 33 par[q]+=par[p]; 34 par[p]=q; 35 } else { 36 par[p]+=par[q]; 37 par[q]=p; 38 } 39 return true; 40 } 41 } f; 42 struct E { 43 int u,v; 44 typec w; 45 friend bool operator < (E a,E b) { 46 return a.w<b.w; 47 } 48 } e[ME]; 49 int le,num,n; 50 typec res; 51 public: 52 void init(int tn){///传入点的个数 53 n=tn; 54 le=res=0; 55 f.init(); 56 num=1; 57 } 58 void add(int u,int v,typec w) { 59 e[le].u=u; 60 e[le].v=v; 61 e[le].w=w; 62 le++; 63 } 64 typec solve(){///返回-1不连通 65 sort(e,e+le); 66 for(int i=0; i<le&&num<n; i++) { 67 if(f.unite(e[i].u,e[i].v)) { 68 num++; 69 res+=e[i].w; 70 } 71 } 72 if(num<n) res=-1; 73 return res; 74 } 75 }gx; 76 struct point{ 77 double x,y; 78 }p[M]; 79 double Distance(point p1,point p2) { 80 return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)); 81 } 82 int main(){ 83 int n,x,y; 84 while(~scanf("%d",&n),n){ 85 scanf("%d%d",&x,&y); 86 for(int i=0;i<n;i++){ 87 scanf("%lf%lf",&p[i].x,&p[i].y); 88 } 89 gx.init(n); 90 x--; 91 y--; 92 if(x>y) swap(x,y); 93 for(int i=0;i<n;i++){ 94 for(int j=i+1;j<n;j++){ 95 if(i==x&&j==y){ 96 gx.add(i,j,0); 97 } 98 else{ 99 gx.add(i,j,Distance(p[i],p[j])); 100 } 101 } 102 } 103 double ans=Distance(p[x],p[y]); 104 ans+=gx.solve(); 105 printf("%.2f ",ans); 106 } 107 return 0; 108 }
Stealing a Cake http://acm.hdu.edu.cn/showproblem.php?pid=4454
从起点走到圆上任意一点,然后从那个点走到矩形上任意一点。求总的路程最小。
考虑起点到圆,只可能走两个切线之间,所以就有一个角度的限制,可以枚举这个角度,然后求出和圆的交点,然后再用这个交点求出到矩形最近距离,所有情况取个最小值。
设起点到圆心的直线sc与坐标轴夹角α。设sc与切线夹角θ 。则我们只要枚举0到θ,就能算出一个交点,注意,要取靠近s的交点。然后通过交点可以算出关于se直线的对称点。这样便枚举了所有可能的点的走法。
当前枚举到的直线斜率是 tan(θ+α) 又知道s经过这个直线,所以就可以算出直线上任意一点。然后就算直线和圆的交点,然后取近的交点,分别和矩形四个边算距离,也是取最小。对称点也同理可得。
1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 using namespace std; 5 const double eps=1e-8; 6 const double pi=acos(-1.0); 7 const int inf=0x3f3f3f3f; 8 struct point { 9 double x,y; 10 } s,c,p[8]; ///起点,圆心,矩形 11 double Distance(point p1,point p2) { 12 return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)); 13 } 14 point intersection(point u1,point u2,point v1,point v2) { 15 point ret=u1; 16 double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x)) /((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x)); 17 ret.x+=(u2.x-u1.x)*t; 18 ret.y+=(u2.y-u1.y)*t; 19 return ret; 20 } 21 void intersection_line_circle(point c,double r,point l1,point l2,point& p1,point& p2) { 22 point p=c; 23 double t; 24 p.x+=l1.y-l2.y; 25 p.y+=l2.x-l1.x; 26 p=intersection(p,c,l1,l2); 27 t=sqrt(r*r-Distance(p,c)*Distance(p,c))/Distance(l1,l2); 28 p1.x=p.x+(l2.x-l1.x)*t; 29 p1.y=p.y+(l2.y-l1.y)*t; 30 p2.x=p.x-(l2.x-l1.x)*t; 31 p2.y=p.y-(l2.y-l1.y)*t; 32 } 33 double xmult(point p1,point p2,point p0) { 34 return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y); 35 } 36 double disptoseg(point p,point l1,point l2) { 37 point t=p; 38 t.x+=l1.y-l2.y,t.y+=l2.x-l1.x; 39 if (xmult(l1,t,p)*xmult(l2,t,p)>eps) return Distance(p,l1)<Distance(p,l2)?Distance(p,l1):Distance(p,l2); 40 return fabs(xmult(p,l1,l2))/Distance(l1,l2); 41 } 42 point ptoseg(point p,point l1,point l2) { 43 point t=p; 44 t.x+=l1.y-l2.y,t.y+=l2.x-l1.x; 45 if (xmult(l1,t,p)*xmult(l2,t,p)>eps) return Distance(p,l1)<Distance(p,l2)?l1:l2; 46 return intersection(p,t,l1,l2); 47 } 48 double jiaotoju(point pp) { 49 double res=inf; 50 for(int i=0; i<4; i++) { 51 res=min(res,disptoseg(pp,p[i],p[i+1])); 52 } 53 return res; 54 } 55 int main() { 56 double r,x1,x2,y1,y2; 57 while(~scanf("%lf%lf",&s.x,&s.y),s.x!=0||s.y!=0) { 58 scanf("%lf%lf%lf",&c.x,&c.y,&r); 59 scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); 60 if(x1>x2) swap(x1,x2); 61 if(y1>y2) swap(y1,y2); 62 p[0].x=x1; 63 p[0].y=y1; 64 p[1].x=x2; 65 p[1].y=y1; 66 p[2].x=x2; 67 p[2].y=y2; 68 p[3].x=x1; 69 p[3].y=y2; 70 p[4]=p[0]; 71 double afa,tanafa;///起点到圆心的直线与x轴夹角,就是直线斜率 72 if(fabs(s.x-c.x)<eps) { 73 afa=90*pi/180; 74 } else { 75 tanafa=(s.y-c.y)/(s.x-c.x); 76 afa=atan(tanafa); 77 } 78 double xita,sinxita;///起点到圆心的直线与切线夹角 79 sinxita=r/Distance(s,c); 80 xita=asin(sinxita); 81 double bigxita=xita; 82 double add=bigxita/1000; 83 double delx,dely,dist1,dist2; 84 point L2,J1,J2,center; 85 double ans=inf,sum; 86 for(double x=0; x<=bigxita; x+=add) { 87 xita=x+afa; 88 delx=10; 89 dely=tan(xita)*delx; 90 L2.x=s.x+delx; 91 L2.y=s.y+dely; 92 intersection_line_circle(c,r,s,L2,J1,J2); 93 dist1=Distance(s,J1); 94 dist2=Distance(s,J2); 95 if(dist1>dist2) { 96 swap(dist1,dist2); 97 swap(J1,J2); 98 } 99 ans=min(ans,dist1+jiaotoju(J1)); 100 center=ptoseg(J1,s,c); 101 J2.x=2*center.x-J1.x; 102 J2.y=2*center.y-J1.y; 103 ans=min(ans,dist1+jiaotoju(J2)); 104 } 105 printf("%.2f ",ans); 106 } 107 return 0; 108 }
事实上从上面的枚举可以看出,正解只有一个,并且一定在α-θ到α+θ之间。并且偏离正解越远,肯定距离越长,那么就是一个开口向上的二次函数,就可以对这个区间三分查找。
1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 using namespace std; 5 const double eps=1e-8; 6 const double pi=acos(-1.0); 7 const int inf=0x3f3f3f3f; 8 struct point { 9 double x,y; 10 } s,c,p[8]; ///起点,圆心,矩形 11 double Distance(point p1,point p2) { 12 return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)); 13 } 14 point intersection(point u1,point u2,point v1,point v2) { 15 point ret=u1; 16 double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x)) /((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x)); 17 ret.x+=(u2.x-u1.x)*t; 18 ret.y+=(u2.y-u1.y)*t; 19 return ret; 20 } 21 void intersection_line_circle(point c,double r,point l1,point l2,point& p1,point& p2) { 22 point p=c; 23 double t; 24 p.x+=l1.y-l2.y; 25 p.y+=l2.x-l1.x; 26 p=intersection(p,c,l1,l2); 27 t=sqrt(r*r-Distance(p,c)*Distance(p,c))/Distance(l1,l2); 28 p1.x=p.x+(l2.x-l1.x)*t; 29 p1.y=p.y+(l2.y-l1.y)*t; 30 p2.x=p.x-(l2.x-l1.x)*t; 31 p2.y=p.y-(l2.y-l1.y)*t; 32 } 33 double xmult(point p1,point p2,point p0) { 34 return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y); 35 } 36 double disptoseg(point p,point l1,point l2) { 37 point t=p; 38 t.x+=l1.y-l2.y,t.y+=l2.x-l1.x; 39 if (xmult(l1,t,p)*xmult(l2,t,p)>eps) return Distance(p,l1)<Distance(p,l2)?Distance(p,l1):Distance(p,l2); 40 return fabs(xmult(p,l1,l2))/Distance(l1,l2); 41 } 42 point ptoseg(point p,point l1,point l2) { 43 point t=p; 44 t.x+=l1.y-l2.y,t.y+=l2.x-l1.x; 45 if (xmult(l1,t,p)*xmult(l2,t,p)>eps) return Distance(p,l1)<Distance(p,l2)?l1:l2; 46 return intersection(p,t,l1,l2); 47 } 48 double jiaotoju(point pp) { 49 double res=inf; 50 for(int i=0; i<4; i++) { 51 res=min(res,disptoseg(pp,p[i],p[i+1])); 52 } 53 return res; 54 } 55 double r; 56 double f(double xita) { 57 double delx,dely,dist1,dist2; 58 point L2,J1,J2,center; 59 delx=10; 60 dely=tan(xita)*delx; 61 L2.x=s.x+delx; 62 L2.y=s.y+dely; 63 intersection_line_circle(c,r,s,L2,J1,J2); 64 dist1=Distance(s,J1); 65 dist2=Distance(s,J2); 66 if(dist1>dist2) { 67 swap(dist1,dist2); 68 swap(J1,J2); 69 } 70 double res=dist1+jiaotoju(J1); 71 center=ptoseg(J1,s,c); 72 J2.x=2*center.x-J1.x; 73 J2.y=2*center.y-J1.y; 74 res=min(res,dist1+jiaotoju(J2)); 75 return res; 76 } 77 double TernarySearch(double L,double R) { /// 三分查找 78 while(R-L>eps) { 79 double LL=(L*2+R)/3; 80 double RR=(L+R*2)/3; 81 if(f(LL)<f(RR)) ///f为对应的值 这里求最小值 82 R=RR; 83 else 84 L=LL; 85 } 86 return L; 87 } 88 int main() { 89 double x1,x2,y1,y2; 90 while(~scanf("%lf%lf",&s.x,&s.y),s.x!=0||s.y!=0) { 91 scanf("%lf%lf%lf",&c.x,&c.y,&r); 92 scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); 93 if(x1>x2) swap(x1,x2); 94 if(y1>y2) swap(y1,y2); 95 p[0].x=x1; 96 p[0].y=y1; 97 p[1].x=x2; 98 p[1].y=y1; 99 p[2].x=x2; 100 p[2].y=y2; 101 p[3].x=x1; 102 p[3].y=y2; 103 p[4]=p[0]; 104 double afa,tanafa;///起点到圆心的直线与x轴夹角,就是直线斜率 105 if(fabs(s.x-c.x)<eps) { 106 afa=90*pi/180; 107 } else { 108 tanafa=(s.y-c.y)/(s.x-c.x); 109 afa=atan(tanafa); 110 } 111 double xita,sinxita;///起点到圆心的直线与切线夹角 112 sinxita=r/Distance(s,c); 113 xita=asin(sinxita); 114 double ans=TernarySearch(afa-xita,afa+xita); 115 printf("%.2f ",f(ans)); 116 } 117 return 0; 118 }
Shoot the Airplane http://acm.hdu.edu.cn/showproblem.php?pid=4458
题意:子弹竖直上抛运动,多边形水平匀速运动。问是否能有一个时间点使得子弹在多边形内。
暴力枚举时间,有了时间就知道子弹的位置和多边形的位置,然后判断点在多边形内就行。注意边上的不算。
1 #include<cstdio> 2 #include<cstdlib> 3 const double eps=1e-8; 4 struct point{ 5 double x,y; 6 }p[32],now[32],s; 7 class PolygonJudge { //任意多边形判定 8 #define zero(x) (((x)>0?(x):-(x))<eps) 9 double xmult(point p1,point p2,point p0) { 10 return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y); 11 } 12 public: 13 int inside_polygon(point q,int n,point p[],int on_edge=1) {//判点在任意多边形内,顶点按顺时针或逆时针给出 14 point q2; 15 const int offset=100;//on_edge表示点在多边形边上时的返回值,offset为多边形坐标上限 16 int i=0,cnt; 17 while (i<n) 18 for (cnt=i=0,q2.x=rand()+offset,q2.y=rand()+offset; i<n; i++) 19 if(zero(xmult(q,p[i],p[(i+1)%n]))&&(p[i].x-q.x)*(p[(i+1)%n].x-q.x)<eps&&(p[i].y-q.y)*(p[(i+1)%n].y-q.y)<eps) 20 return on_edge; 21 else if (zero(xmult(q,q2,p[i]))) 22 break; 23 else if (xmult(q,p[i],q2)*xmult(q,p[(i+1)%n],q2)<-eps&&xmult(p[i],q,p[(i+1)%n])*xmult(p[i],q2,p[(i+1)%n])<-eps) 24 cnt++; 25 return cnt&1; 26 } 27 } gx; 28 int main(){ 29 int v,b,g,n; 30 while(~scanf("%d%d%d",&v,&b,&g),v|b|g){ 31 scanf("%d",&n); 32 for(int i=0;i<n;i++){ 33 scanf("%lf%lf",&p[i].x,&p[i].y); 34 } 35 double bigt; 36 if(g){ 37 bigt=2.0*b/g; 38 } 39 else{ 40 bigt=120.0/b; 41 } 42 double add=bigt/10000; 43 bool flag=false; 44 double ans; 45 for(double t=0;t<=bigt;t+=add){ 46 s.x=0; 47 s.y=b*t-0.5*g*t*t; 48 for(int i=0;i<n;i++){ 49 now[i]=p[i]; 50 now[i].x+=v*t; 51 } 52 if(gx.inside_polygon(s,n,now,0)){ 53 flag=true; 54 ans=t; 55 break; 56 } 57 } 58 if(!flag) puts("Miss!"); 59 else{ 60 printf("%.2f ",ans); 61 } 62 } 63 return 0; 64 }
还有一种解法,相对运动的思想,多边形向左运动,相当于多边形不动,子弹向右有一样的速度,那么子弹就是个抛物线,求抛物线是否进入多边形内。至今没敲出来,先放一放。
end