/* 一道艰难的实训题 */

单点时限: 2.0 sec

内存限制: 256 MB

A triangle is a basic shape of planar geometry. It consists of three straight lines and three angles in between. Sides are usually labeled a,b,c, with their opposite angles labeled α,β,γ respectively.

A look into a book about geometry shows that the following formulas exists:

The values of a,b,c,α,β,γ forms a set of six parameters that fully define a triangle. If a large enough set of parameters are given, the missing ones can be calculated using the formulas above.

You are to write a program that calculates the missing parameters for a given subset of the six parameters of a triangle. For some sets of parameters, it is not possible to calculate the triangle because either too few is known about the triangle or the parameters would lead to an invalid triangle. The sides of a valid triangle are greater than 0 and the angles are greater than 0 and less than π. Your program should detect this case and output: Invalid input. The same phrase should be output if more than the minimal set needed to compute the triangle is given but the parameters conflict with each other, e.g. all three angles are given but their sum is greater than π.

Other sets of parameters can lead to more than one but still a finite number of valid solutions for the triangle. In such a case, your program should output: “More than one solution.”

In all other cases, your program should compute the missing parameters and output all six parameters.

输入格式
The first line of the input file contains a number indicating the number of parameter sets to follow. Each following line consists of six numbers, separated by a single blank character. The numbers are the values for the parameters a,α,b,β,c,γ respectively. A value of −1 indicates that the corresponding parameter is undefined and has to be calculated. All floating-point numbers include at least eight significant digits.

输出格式
Your program should output a line for each set of parameters found in the input file. If a unique solution for a valid triangle can be found for the given parameters, your program should output the six parameters a,α,b,β,c,γ separated by a blank character. Otherwise the line should contain the phrase More than one solution. or Invalid input. as explained above.

The numbers in the output file should include at least six significant digits. Your calculations should be precise enough to get the six most significant digits correct (i.e. a relative error of 0.000001 is allowed).

样例

input
4
47.9337906847 0.6543010109 78.44555175791.4813893731 66.5243757656 1.0059022695
62.72048064 2.26853639 -1.00000000 0.56794657 -1.00000000 -1.00000000
15.69326944 0.24714213 -1.00000000 1.80433105 66.04067877 -1.00000000
72.83685175 1.04409241 -1.00000000 -1.00000000 -1.00000000 -1.00000000
output
47.933791 0.654301 78.445552 1.481389 66.524376 1.005902
62.720481 2.268536 44.026687 0.567947 24.587225 0.305110
Invalid input.
Invalid input.

解题思路
比较棘手的一道题,题意就是通过给出的条件解出−1-1−1所代表的元素,初中解三角形的功底要扎实,对各种情况分类讨论。

  1. 无效输入的情况:
    ① 题目所给的数据少于三个,无法得到一个解(计算前判断)
    ② 要素无法构成三角形(judge函数,计算后判断):
    1. 仍有未知项(即-1)
    2. 三个角之和不等于π\piπ
    3. 两边之和小于第三边
    4. 不满足正弦定理
  2. 求解三角形:
  3. 判断解的个数:
    已知两边和其中一边的对角不能唯一确定三角形,可能出现两解,一解或无解的情况。在本题中使用正弦定理来判断。
    若已知 a、b、αa、b、\alphaa、b、α,由正弦定理可以得到sinβ=bsinαasin\beta=\frac{bsin\alpha}{a}sinβ=absinα​,若sinβ>1sin\beta>1sinβ>1,无解;若sinβ=1sin\beta=1sinβ=1,一解;若sinβ<1sin\beta<1sinβ<1两解。在代码中则通过比较 aaa 与 bsinαbsin\alphabsinα 的大小来判断。

代码思路
写代码的时候没有怎么打注释,所以解释一下。
由于题目有精度要求,所以宏定义一个小数mask。
在输入时指定ccc和eee来分别储存已知的角和边的个数。
首先定义三个函数

  1. 已知三边时调用getagetageta函数求角
  2. 已知两边及其夹角时调用getegetegete函数求对边
  3. c=2c=2c=2 时调用 c2cc2cc2c 函数求第三个角
  4. e=3e=3e=3 时调用 e2ce2ce2c 求所有的角

之后进入主函数

  1. 读入数据并记录已知元素个数;
  2. 判断元素数量是否满足最低限度;
  3. 仅根据已知边或角的数量来处理:已知两角求第三个角或已知三边求所有角;
  4. 边角情况混合处理:
    (1)已知一边及其对角(a,α)(a,\alpha)(a,α),此时可以解出来的情况有(−1,β)(-1,\beta)(−1,β)或(b,−1)(b,-1)(b,−1);
    ①(−1,β)(-1,\beta)(−1,β),用正弦定理求出bbb;
    ②(b,−1)(b,-1)(b,−1),此时需要根据 sinβsin\betasinβ 来判断解的情况;
    (2)已知两边和未知边的对角,直接调用 getegetegete 函数解出第三边;
  5. 至此我们好像已经遍历了所有情况,只需要循环至所有元素都被解出来;
  6. 调用 judgejudgejudge 函数判断元素是否可以组成三角形,判断是否有多解;
  7. 输出。

ac代码

#include <bits/stdc++.h>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
const long double pi=4*atan(1);
const long double mask=1e-6;
long double a[6];long double geta(long double a,long double b,long double c)
{return acos((a*a+b*b-c*c)/(2*a*b));
}long double gete(long double x,long double y,long double c)
{return sqrt(x*x+y*y-2*x*y*cos(c));
}void c2c()
{long double t=0;for(int i=1;i<6;i+=2){if(a[i]<0)continue;t+=a[i];}for(int i=1;i<6;i+=2)if(a[i]<0)a[i]=pi-t;
}void e2c()
{for(int i=1;i<6;i+=2)if(a[i]<0)a[i]=geta(a[(i+1)%6],a[(i+3)%6],a[i-1]);
}bool judge()
{for(int i=0;i<6;i++)if(a[i]<0)return false;if(fabs(a[1]+a[3]+a[5]-pi)>mask)return false;if(a[0]+a[2]<=a[4]||a[2]+a[4]<=a[0]||a[0]+a[4]<=a[2])return false;for (int i = 0; i < 4; i += 2) if (fabs(a[i]*sin(a[i+3])-sin(a[i+1])*a[i+2])>mask)return false;return true;
}int main(int argc, char** argv)
{int T;cin >> T;while(T--){int n=0,c=0,e=0;bool flag=false;for(int i=0;i<6;i++){cin >> a[i];if(a[i]>0){n++;if(i&1) c++;else e++;}}if(n<3){cout << "Invalid input." << endl;continue;}while(n<6){int s=n;if(c==2){c2c();n++;c=3;}if(e==3){e2c();n+=3-c;c=3;}for(int i=0;i<6;i+=2){if(a[i]>0&&a[i+1]>0){for(int j=0;j<6;j+=2){if((a[j]>0&&a[j+1]>0)||(a[j]<0&&a[j+1]<0))continue;if(a[j]<0){a[j]=a[i]/sin(a[i+1])*sin(a[j+1]);n++;e++;}else{if(a[i+1]<pi/2&&a[i]<a[j]&&a[i]>a[j]*sin(a[i+1]))flag=true;double temp=sin(a[i+1])*a[j]/a[i];if(temp>1||temp<0)continue;a[j+1]=asin(sin(a[i+1])*a[j]/a[i]);n++;c++;}}}}if(e==2){for(int i=0;i<6;i+=2){if(a[i]<0&&a[i+1]>0){a[i]=gete(a[(i+2)%6],a[(i+4)%6],a[i + 1]);n++;e++;}}}if(s==n)break;}if(judge()){if(flag)cout << "More than one solution." << endl;else{for(int i=0;i<5;i++)cout << fixed << setprecision(6) << a[i] << " ";cout << fixed << setprecision(6) << a[5] << endl;}}elsecout << "Invalid input." << endl;}return 0;
}

补充
有位带哥提醒我 π\piπ 可以用M_PI表示,更方便些

EOJ 1594. Triangle相关推荐

  1. [JS][C++]两题斐波那契数列:上台阶、triangle

    上台阶 时间限制: 3000MS 内存限制: 589824KB 题目描述: 有一楼梯共m级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第m级,共有多少走法? 注:规定从一级到一级有0种走法. ...

  2. 设计一个扩展自抽象类geometricobject的新的triangle类_C++ 接口(抽象类)

    C++ 接口(抽象类) 接口描述了类的行为和功能,而不需要完成类的特定实现. C++ 接口是使用抽象类来实现的,抽象类与数据抽象互不混淆,数据抽象是一个把实现细节与相关的数据分离开的概念. 如果类中至 ...

  3. 帕斯卡三角形(Pascal's triangle)

    // The following code is compiled on VC2005 // #include "stdafx.h" /*--------------------- ...

  4. [leedcode 118] Pascal's Triangle

    Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5, Retu ...

  5. [LeetCode 120] - 三角形(Triangle)

    问题 给出一个三角形,找出从顶部至底部的最小路径和.每一步你只能移动到下一行的邻接数字. 例如,给出如下三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] 从顶部至底部的最 ...

  6. D - Triangle Partition HDU - 6300 sort(cmp)

    D - Triangle Partition HDU - 6300 题解 由于三点不共线,且三角形不相交,则对坐标排序,输出 #include<bits/stdc++.h> using n ...

  7. Leetcode 118:Pascal's Triangle 杨辉三角

    118:Pascal's Triangle 杨辉三角 Given a non-negative integer numRows, generate the first numRows of Pasca ...

  8. mysql 1594_【MySQL】复制1594错误(从库relaylog损坏)

    现象: mysql> show slave status\G; *************************** 1. row *************************** -- ...

  9. LintCode: Triangle

    C++ 逆推 1 class Solution { 2 public: 3 /** 4 * @param triangle: a list of lists of integers. 5 * @ret ...

最新文章

  1. 高手速成android开源项目【blog篇】
  2. Java-Maven(四):Eclipse集成Maven环境配置
  3. java socket编程客户端_Java Socket编程 - 基于Socket实现HTTP下载客户端
  4. 2020 Pwn2Own东京大赛落幕,Master of Pwn 诞生
  5. mysql事务ACID实现原理_一文解析:MySQL事务ACID原理让你面试不再害怕
  6. [JNI] 开发基础(6)字符串相关操作
  7. can总线程序讲解_CAN总线软件编程
  8. 蓝桥杯-奇妙的数字(2015-A-3)
  9. Java面试题--搜索(solrelasticsearch)
  10. android ios 对比 组件_Android、iOS历史版本对比
  11. 炫酷3D相册 520七夕情人节表白网页制作(HTML+CSS+JavaScript)
  12. 那些年我准备的前端面试题
  13. 光模块调式总结(SFP)
  14. “任期”已近20年,这个AI训练工具有点儿问题
  15. 《指数基金投资指南》 阅读笔记
  16. 基于PL/SQL的数据库备份方法
  17. 我的jQuery学习之路(笔记)——四
  18. C语言对称矩阵的判定
  19. R语言 forestplot 包画森林图
  20. 【对抗攻击论文笔记】对抗迁移性:Delving Into Transferable Adversarial Examples And Black-Box Attacks

热门文章

  1. 黄冈师范计算机学院在哪个校区,黄冈师范学院有几个校区,哪个校区最好及各校区介绍...
  2. jq删除某个css样式,jq删除属性_使用jquery删除css属性或样式
  3. C语言union(联合体)的使用总结
  4. Executor, ExecutorService 和 Executors 间的不同
  5. 高并发的大数据量查询导致系统频繁死机
  6. JQuery笔记-通过tag、class、id获取指定的dom
  7. 如何用单片机实现基于电磁感应的无线充电系统
  8. 转回原来服务器物品带锁吗,藏宝阁带移民锁物品跨服出售功能说明
  9. 分治法大整数乘法c语言,大整数乘法(分治法)
  10. 基于matlab的z-score标准化方法处理数据