zoukankan      html  css  js  c++  java
  • 2012 Asia Hangzhou Regional Contest

    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 }
    View Code

     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 }
    View Code

    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 }
    View Code

    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 }
    View Code

    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 }
    View Code

    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 }
    View Code

     事实上从上面的枚举可以看出,正解只有一个,并且一定在α-θ到α+θ之间。并且偏离正解越远,肯定距离越长,那么就是一个开口向上的二次函数,就可以对这个区间三分查找。

      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 }
    View Code

    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 }
    View Code

    还有一种解法,相对运动的思想,多边形向左运动,相当于多边形不动,子弹向右有一样的速度,那么子弹就是个抛物线,求抛物线是否进入多边形内。至今没敲出来,先放一放。

    end

  • 相关阅读:
    刷题--两个链表生成相加链表
    机器学习与模式识别之——组合模型
    阅读笔记--CSI fingerprinting with SVM regression to achieve device-free passive localization
    复制含有随机指针节点的链表
    将数组排列成左边小,中间相等,右边大的形式 给定链表节点数组和某个值
    EDA(Experimental Data Analysis)之常见分析方法总结--以kaggle的泰坦尼克号之灾为例
    Data Analysis with Python : Exercise- Titantic Survivor Analysis | packtpub.com
    ubuntu16.04配置搜狗输入法
    用栈来求解hanoi塔问题
    codeforces 792 B. Counting-out Rhyme 约瑟夫环
  • 原文地址:https://www.cnblogs.com/gaolzzxin/p/3947987.html
Copyright © 2011-2022 走看看