啊哈哈哈哈哈哈哈哈哈终于a了一道题了哈哈哈哈哈哈哈
由于是学姐(?)出的所以先放上原题:
题目描述
给出一条直线,n 组询问,每组询问一个点的坐标,求这个点关于这条直线的
对称点,输出对称点的坐标。
输入输出格式
输入格式
第一行四个数 x1 , y1 , x2 , y2 , 描述一条线。之后一行一个数字 n, 接下来 n 行每行
两个整数 x, y 表示一个点坐标,保证点不在直线上。
输出格式
输出 n 行,分别为输入给出点的对称点的坐标,误差不超过1e-3即可。
接下来是改的题
题目描述
⑨正在学习高中数学。有一天她看到这样一个问题。
给出一条直线,n 组询问,每组询问一个点的坐标,求这个点关于这条直线的
对称点,输出对称点的坐标。
⑨并不会,于是她把这个问题交给了你。
输入输出格式
输入格式
第一行四个数 x1 , y1 , x2 , y2 , 描述一条线。之后一行一个数字 n, 接下来 n 行每行
两个整数 x, y 表示一个点坐标,保证点不在直线上。
输出格式
输出 n 行,分别为输入给出点的对称点的坐标,误差不超过1e-3即可。
附上我手写的正解:
1 #include<cstdio> 2 using namespace std; 3 int main() 4 { 5 freopen("line.in","r",stdin); 6 freopen("line.out","w",stdout); 7 int x1,y1,x2,y2,x,y,n; 8 double a,b,c,d,ansx,ansy; 9 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 10 a = y1 - y2; 11 b = x2 - x1; 12 c = x1 * y2 - x2 * y1; 13 scanf("%d",&n); 14 for(int i = 0;i < n;i++){ 15 scanf("%d%d",&x,&y); 16 d = a * a + b * b; 17 ansx = (b * b * x - 2 * a * c - a * a * x - 2 * a * b * y) / d; 18 ansy = (a * a * y - 2 * b * c - b * b * y - 2 * a * b * x) / d; 19 printf("%.3lf %.3lf ",ansx,ansy); 20 } 21 return 0; 22 }
这个是……我导出来的公式:
由两个点(x1,y1)(x2,y2)求出的直线的解析式:(y1 - y2)x - (x1 - x2)y + x1y2 - x2y1 = 0
然后设这条直线解析式为ax+by+c=0,给出的点坐标(x1,y1),要求的点(x2,y2),则
(a2 + b2)y2 = -2bc - 2abx1 - b2y1 + a2y1
(a2 + b2)x2 = -2ac - a2x1 + b2x1 - 2aby1
嗯,纯手推的式子
另外我认为⑨考不上高中(