点开了一个挑战题,不知道规则,第一个就当学习经验了。
两个小时,憋不住去趟厕所回来,时间不够了。另外,在自己机器和在线编译不一样。提交了也编译不正确。比如我声明了
struct ptr{};
然后用
struct ptr dot[n];
来声明数组,结果在线编译不成功:
23: error:: error: C2143: syntax error: : missing ';' before 'type'
然后搜到一篇说这个错误是VC编译器造成的(那就是说我用GCC编译成功不算,必须提交网上,按VC算?),说是变量声明在函数调用之后就会出错(函数调用不用使用本变量,任何一个函数调用皆可)。
如果真把结构体数组的声明放前边,更不可能成功,因为我要靠一个scanf来获得n的值啊~~~
20: error:: error: C2057: expected constant expression
20: error:: error: C2466: cannot allocate an array of constant size 0
20: error:: error: C2133: 'dot' : unknown size
除非,既然说了上限是1001,我就建立一个1001大小的固定数组?虽然很弱智很浪费空间,但是能避免这个错误。如下:
unsigned int n = 1001;
struct ptr dot[n];
这样,想获取新的n,比如3,可以直接覆盖,如果死活不让我scanf来更新n,好歹可以凑合进行下去。不过问题是有三个循环,那样要跑1000×1000×1000的数量级,很没有必要,而且,多余的那么多结构体,是不是要弄个初始值,到时候又怎么计算他们?不应该计算他们的。多余的点根本不应该存在~!
经实测,这样也不行:
20: error:: error: C2057: expected constant expression
20: error:: error: C2466: cannot allocate an array of constant size 0
20: error:: error: C2133: 'dot' : unknown size
不能使用
struct ptr dot[n];
即使前边定义了n为1001~!(感觉这个编译器挺坑啊~!)
其实就是遍历了:
三层循环,第一层是定点A,A依次尝试所有点。
第二层和第三层没什么差别,就是B和C。
只不过,要记得ABC三点出现重复时用个continue(自增运算可不行,会越界)跳过去。
难点就是循环最内层那个核心的角度处理功能:
很久不接触各种三角运算符,加上math里的函数也不经常用,尴尬了。
角度的计算公式都是现查的,现学现用,去网上倒是查到了atan2()函数,但是~遇到一个问题——角度不是死的,还需要想办法。
解决角度的思路:
使用相对坐标,确定了A坐标以后,把A坐标看成(0,0),B和C的坐标以A为零点,确定新的相对坐标;
atan2()函数是针对纵坐标差和横坐标差的,输出的结果是这对坐标差构成的——直线——相对x坐标轴的角度差~!也就是说,这是针对一条直线来的,不是针对两条线的夹角,我的解决办法就是分别给两条直线计算出和X轴的相对夹角,然后计算角度差。
还包括四个象限的处理问题。
依然有很多问题没有解决:
当时不停更改,变量设的也多而杂、有冗余,还有些“对付”上的代码,先把本地代码传上来存下:
1 #include<stdio.h> 2 #include<math.h> 3 //思路,遍历,三层循环,第一重循环找所有的点,第二重和第三重组成其他两点的所有组合>。 4 //不打算用数据结构了,自己记住有几个点 5 //但是点太多怎么动态储存呢?malloc 6 #define PI 3.1415926 7 struct ptr{ 8 double x; 9 double y; 10 } 11 12 main(){ 13 //get n 14 //加非法判断?3到1001~! 15 unsigned int n; 16 int i,j,k; 17 double tempAngle = 0; 18 double maxAngle = 0; 19 //记录结果的三个结构体变量 20 struct ptr A,B,C; 21 printf("input n:i\n"); 22 scanf("%d",&n); 23 //临时变量 24 struct ptr tempj; 25 struct ptr tempk; 26 double angleKtoZero; 27 double angleJtoZero; 28 double tempx; 29 double tempy; 30 31 struct ptr dot[n]; 32 for(i = 0;i < n;i++){ 33 scanf("%lf %lf",&(dot[i].x),&(dot[i].y)); 34 } 35 //遍历所有组合 36 for(i = 0;i < n;i++){ 37 for(j = 0;j < n;j++){//需要消除重复,跳过去直接 38 if(j == i) 39 continue; 40 for(k = 0;k < n;k++){ 41 if(k == j || k == i) 42 continue; 43 // 计算角度,存在哪?用一对变量,只要比他大,替换? 44 //atan应该排除负数情况,用绝对值对比~!不然容易出现差错, 45 //要不然就以A为0 0,把B C 转换成相对坐标。 46 tempj.x = dot[j].x - dot[i].x; 47 tempj.y = dot[j].y - dot[i].y; 48 tempk.x = dot[k].x - dot[i].x; 49 tempk.y = dot[k].y - dot[i].y; 50 tempx = tempj.x - tempk.x; 51 tempy = tempj.y - tempk.y; 52 /* if(tempx < 0) 53 tempx = -tempx;//not -= 54 if(tempy < 0) 55 tempy = -tempy; 56 */ 57 angleKtoZero = atan2(tempj.x,tempj.y) * 180 / PI; 58 angleJtoZero = atan2(tempk.x,tempk.y) * 180 / PI; 59 //test 60 printf("%lf\n",angleJtoZero); 61 printf("%lf\n",angleKtoZero); 62 63 tempAngle = angleKtoZero - angleJtoZero; 64 if(tempAngle < 0){ 65 tempAngle = -tempAngle; 66 } 67 if(tempAngle > 181){//因为不是严格180,先这么写 68 tempAngle -= 180; 69 } 70 double add; 71 add = tempAngle * 100000 % 10; 72 if(add >= 5) 73 tempAngle = tempAngle * 100000/10 + add; 74 else 75 tempAngle = tempAngle * 100000/10; 76 77 //现在主要不知道怎么解决角度大于90度的情况,因此时角度越大, tan反而越小 78 //直接用y的差距比上x的差距,是不是也太片面了,不是固定A为0点 79 //那就想办法创造以A为准的坐标系? 80 if(tempAngle > maxAngle){ 81 maxAngle = tempAngle; 82 A.x = dot[i].x; 83 A.y = dot[i].y; 84 B.x = dot[j].x; 85 B.y = dot[j].y; 86 C.x = dot[k].x; 87 C.y = dot[k].y; 88 } 89 } 90 } 91 } 92 93 printf("The maxAngle is %lf\n",maxAngle); 94 printf("A:%lf %lf\n",A.x,A.y); 95 printf("B:%lf %lf\n",B.x,B.y); 96 printf("C:%lf %lf\n",C.x,C.y); 97 98 99 }
根据“反闭门造车”理论,这是我做的第一个题,即使解不出来也不能全当是个练习,最好是找找答案,学习一下现成的,成熟的解决方法,希望能找到参考答案。
另外,这是3星难度,还有2星难度,应该先看看2星难度的,循序渐进。
http://blog.csdn.net/type_q/article/details/24512223