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

时间:2023-03-09 02:53:38
NBUT 1121 Sakuya's Fly Knife 飞刀(暴力)

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

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

 #include<bits/stdc++.h>
using namespace std;
bool tar[][];//标出每个靶子
int x[],y[];//记录每个靶子的坐标
map<double,int> mapp1,mapp2; void cal(int n,int m,int t)
{
int ans[]={,,};//答案
for(int i=; i<n; i++)
{
for(int j=; j<m; j++)
{
if(!tar[i][j]) //对于每个非有刀格子
{
mapp1.clear();
mapp2.clear();
int cnt_l=,cnt_r=;
for(int k=; k<t; k++)//扫描所有的target
{
if(y[k]>j) //上边的
{
double q=(double)(y[k]-j)/(x[k]-i);
if(mapp1[q]<=)
mapp1[q]=;
}
else if(y[k]<j) //下边的
{
double q=(double)(y[k]-j)/(x[k]-i);
if(mapp2[q]<=)
mapp2[q]=;
}
else //同一行的
{
if(x[k]>i) //同行左边
cnt_l=;
else //同行右边
cnt_r=;
}
}
if(ans[]>cnt_l + cnt_r + mapp1.size()+mapp2.size())//有更少的,则更新答案
{
ans[]=cnt_l + cnt_r + mapp1.size() + mapp2.size();
ans[]=i;
ans[]=j;
}
}
}
}
printf("(%d, %d) %d\n",ans[],ans[],ans[]);
} int main()
{
//freopen("e://input.txt","r",stdin);
int n, m, t, a, b;
while(cin>>n>>m)
{
memset(tar,,sizeof(tar));
scanf("%d",&t);
for(int i=; i<t; i++)
{
scanf("%d%d",&x[i],&y[i]);
tar[x[i]][y[i]]=true;
}
cal(n,m,t);
} return ;
}

AC代码