• NBUT 1121 Sakuya's Fly Knife 飞刀(暴力)


    题意:给出一个带有n*m个格子的矩阵,部分格子中有靶子target,现在要从一个没有靶子的格子中射出飞刀数把,飞刀是可穿透靶子的,同一直线上都可以一刀全射掉。现在问在哪个格子射出飞刀,可以在全部射中的情况下用刀次数最少?有target的格子不可选。

    思路:穷举所有没有靶子的格子,计算每个靶子的角度,若角度相同就是可以一刀解决的。这里角度可能用的是实数的,用map解决。需要注意的是,在判断角度时,可能有重复,比如: 。t。。x。t。。 这里的x代表飞刀的出发点,‘t’代表靶子,那么两边的 t 计算出来的角度是相同的(按照靶子坐标的x/y来算角度即可)。需要做的只是对上下两边进行区分即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 bool tar[105][105];//标出每个靶子
     4 int x[105],y[105];//记录每个靶子的坐标
     5 map<double,int> mapp1,mapp2;
     6 
     7 void cal(int n,int m,int t)
     8 {
     9     int ans[3]={1000,1000,1000};//答案
    10     for(int i=0; i<n; i++)
    11     {
    12         for(int j=0; j<m; j++)
    13         {
    14             if(!tar[i][j])  //对于每个非有刀格子
    15             {
    16                 mapp1.clear();
    17                 mapp2.clear();
    18                 int cnt_l=0,cnt_r=0;
    19                 for(int k=0; k<t; k++)//扫描所有的target
    20                 {
    21                     if(y[k]>j)  //上边的
    22                     {
    23                         double q=(double)(y[k]-j)/(x[k]-i);
    24                         if(mapp1[q]<=0)
    25                             mapp1[q]=1;
    26                     }
    27                     else if(y[k]<j) //下边的
    28                     {
    29                         double q=(double)(y[k]-j)/(x[k]-i);
    30                         if(mapp2[q]<=0)
    31                             mapp2[q]=1;
    32                     }
    33                     else    //同一行的
    34                     {
    35                         if(x[k]>i)  //同行左边
    36                             cnt_l=1;
    37                         else    //同行右边
    38                             cnt_r=1;
    39                     }
    40                 }
    41                 if(ans[0]>cnt_l + cnt_r + mapp1.size()+mapp2.size())//有更少的,则更新答案
    42                 {
    43                     ans[0]=cnt_l + cnt_r + mapp1.size() + mapp2.size();
    44                     ans[1]=i;
    45                     ans[2]=j;
    46                 }
    47             }
    48         }
    49     }
    50     printf("(%d, %d) %d
    ",ans[1],ans[2],ans[0]);
    51 }
    52 
    53 
    54 int main()
    55 {
    56     //freopen("e://input.txt","r",stdin);
    57     int n, m, t, a, b;
    58     while(cin>>n>>m)
    59     {
    60         memset(tar,0,sizeof(tar));
    61         scanf("%d",&t);
    62         for(int i=0; i<t; i++)
    63         {
    64             scanf("%d%d",&x[i],&y[i]);
    65             tar[x[i]][y[i]]=true;
    66         }
    67         cal(n,m,t);
    68     }
    69 
    70     return 0;
    71 }
    AC代码
  • 相关阅读:
    华为内部面试题库(20)
    华为内部面试题库(18)
    华为内部面试题库(14)
    华为内部面试题库(12)
    华为内部面试题库(16)
    华为内部面试题库(17)
    华为内部面试题库(11)
    华为内部面试题库(13)
    Windows 危险的注册表键
    逆向工程师要学什么?
  • 原文地址:https://www.cnblogs.com/xcw0754/p/4544698.html
Copyright © 2020-2023  润新知