题目
解析
两点确定一条直线,而只需要同时对斜率和截距去重,就能判断两条直线是否是同一直线:如果两条直线的斜率相等,并且截距也相等,就说明是同一条直线。与x轴或者y轴平行的直线另外计算。这样就得到了一个较清晰的思路:
- 生成所有点
- 判断所有两两点确定的直线,去重
有几个点需要注意别踩坑:
- 斜率和截距不一定是整数,用double
- 截距的计算
- 去重用set
- 坐标可以用pair
- 不要忘记最后加上与x轴或者y轴平行的直线
答案
40257
代码
#include <bits/stdc++.h>
using namespace std;
vector<pair<int,int>> p;
int ans = 0;
int N =20, M = 21;
set<pair<double,double>>s; //set的作用是去重
//生成所有点到数组
void getPoint(){
for(int i =0;i<N;i++)
for(int j=0;j<M;j++) p.push_back(make_pair(i,j));
}
//将两点确定的直线的斜率和截距放进set里
void countLine(int i, int j){
int x1 = p[i].first , y1 = p[i].second;
int x2 = p[j].first , y2 = p[j].second;
if(x1 == x2 || y1 == y2) return;
double fm = (x2 - x1) * 1.0;
double k = (y2-y1)*1.0/ (x2-x1);
double b = (y1*x2 - x1*y2) * 1.0 / fm;
s.insert(make_pair(k,b));
}
void solve(){
getPoint();
int n = p.size();
//每个点,和这个点后面的所有点做一次计算
for(int i = 0;i<n;i++)
for(int j = i+1;j<n;j++)
countLine(i,j);
ans = s.size() + N + M; //结果就是set的大小,加上和x轴y轴平行的直线的数量
}
int main(){
solve();
cout<< ans << endl;
return 0;
}
又写了一次代码,如下
#include <bits/stdc++.h>
using namespace std;
typedef pair<double, double> PII;
const int N = 20, M = 21;
set<PII> st;
void check(int x1, int y1, int x2, int y2) {
if (x1 == x2 || y1 == y2) return;
double k = (y2 - y1) * 1.0 / (x2 - x1);
double b = (y1*x2 - x1*y2) * 1.0 / (x2 - x1);
st.insert({k, b});
}
int main() {
for (int i = 0; i < N; i ++)
for (int j = 0; j < M; j ++)
for (int k = 0; k < N; k ++)
for (int l = 0; l < M; l ++)
check(i, j, k, l);
cout << st.size() + N + M <<endl;
return 0;
}