本题答案:40257
解题思路:两点确定一条直线,利用直线的一般表达式Ax+By+C=0便利所有的坐标组求出A,B,C约分后去重(此时得到不平行于x轴与y轴的直线),最后在加上平行于x轴与y轴的直线数。
#include<bits/stdc++.h>
using namespace std;
#define row 21
#define col 20
// 定义一个结构体储存坐标
struct SPOT{
int x;
int y;
}spot[row*col];
// 定义一个结构体储存直线系
struct LINE{
int A;
int B;
int C;
int value; //用于标记不平行于x轴与y轴的直线数量,初始化为1
}line[1000000];
int ans=0;//统计直线的数量
int gcd(int a,int b){
if(b==0) return a;
return gcd(b,a%b);
}
int fun(int x1,int y1,int x2, int y2){
int A,B,C;
// 不统计平行于x轴与y轴的直线
if(x1==x2) return 0;
if(y1==y2) return 0;
if(x1!=x2&&y1!=y2){
A=y1-y2;
B=x2-x1;
C=x1*y2-y1*x2;
}
int gcdd;
if(C==0) {
gcdd=gcd(A,B);
}
else {
gcdd=gcd(gcd(A,B),C);
}
line[ans].A=A/gcdd;
line[ans].B=B/gcdd;
line[ans].C=C/gcdd;
line[ans].value=1;
ans++;
return 0;
}
int main(){
int k=0;
// 将坐标储存到结构体中
for(int i=0;i<col;i++){
for(int j=0;j<row;j++){
spot[k].x=i;
spot[k].y=j;
k++;
}
}
// 循环遍历坐标系的任意两个点
for(int i=0;i<col*row;i++){
for(int j=i+1;j<col*row;j++){
fun(spot[i].x,spot[i].y,spot[j].x,spot[j].y);
}
}
// 去重
for(int i=1;i<ans;i++){
for(int j=0;j<i;j++){
if(line[i].A==line[j].A&&line[i].B==line[j].B&&line[i].C==line[j].C){
line[i].value=line[i-1].value; //若为相同的一条直线,其value值与上一条直线相同
break;
}
line[i].value=line[i-1].value+1; //若为不同的两条直线,其value值加1
}
}
cout<<line[ans-1].value+row+col; //结果为最后一条直线的value值加上平行于x轴与y轴的直线的数量
return 0;
}