第十二届蓝桥杯 直线 填空题 两种做法
答案:40257
由给定两点求直线的一般式Ax+By+C=0;
A=y1-y2
B=x2-x1
C=x1y2-x2y1
当保证AB互质时,三个参数唯一确定一条平面直线
解法一:用一般式表示直线,然后用set去重
import java.util.*;
public class Main
{
static class line
{
int a,b,c;
public line(int x,int y,int z)
{
a=x;b=y;c=z;
}
/* (非 Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + a;
result = prime * result + b;
result = prime * result + c;
return result;
}
/* (非 Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
line other = (line) obj;
if (a != other.a)
return false;
if (b != other.b)
return false;
if (c != other.c)
return false;
return true;
}
}
static int gcd(int a,int b)
{
if(b==0)return a;
return gcd(b,a%b);
}
static HashSet<line> l=new HashSet<>();
static int idx=0,ans=0;
public static void main(String args[])
{
Scanner sc=new Scanner(System.in);
for(int x1=0;x1<20;x1++)
for(int y1=0;y1<21;++y1)
for(int x2=0;x2<20;++x2)
for(int y2=0;y2<21;++y2)
{
if(x1==x2&&y1==y2)continue;
int a,b,c,gcd;
a=y1-y2;
b=x2-x1;
c=x1*y2-x2*y1;
gcd=gcd(a,b);
a/=gcd;
b/=gcd;
c/=gcd;
l.add(new line(a,b,c));
}
System.out.println(l.size());
}
}
解法二:用斜截式表示直线,然后排序,对相邻的直线手动判重
import java.util.*;
public class Main
{
static class line
{
double k,b;
public line(double x,double y)
{
k=x;b=y;
}
}
static class mcomp implements Comparator<line>
{
@Override
public int compare(line a, line bb) {
if(Math.abs(a.k-bb.k)<1e-8)
{
if(a.b<bb.b)return -1;
else return 1;
}
if(a.k<bb.k)return -1;
else return 1;
}
}
static line l[]=new line[180000];
static int idx=0;
public static void main(String args[])
{
Scanner sc=new Scanner(System.in);
for(int x1=0;x1<20;x1++)
for(int y1=0;y1<21;++y1)
for(int x2=0;x2<20;++x2)
for(int y2=0;y2<21;++y2)
{
if(x1!=x2)
{
double k=(double)(y2-y1)/(x2-x1);
double b=(double)y1-k*x1;
l[idx++]=new line(k,b);
//System.out.println(l[idx-1].k);
}
}
Arrays.sort(l,0,idx,new mcomp());
int res=1;
for(int i=1;i<idx;++i){
if(Math.abs(l[i].k-l[i-1].k)>1e-6||Math.abs(l[i].b-l[i-1].b)>1e-6)
res++;
}
res+=20;
System.out.println(res);
}
}