2014 携程编程资格赛总结
比赛一开始,首先看题,第一题,是一道数论的题,想了几下,发现没有水到我能做的地步,跳过;然后是第二题,以前应该见过,但是没有做出来,想了几分钟,没有结果,之后Hogg大牛说是做过的一道DP。。。。。。DP无感,跳过;然后第三题,我比较熟悉的计算几何,想想是比较水的,而且几个计算公式也有(竟然最后杯具了。。。),还提醒一下Hogg大牛做完第二题可以去看看这题。。。。。。然后想着先看完所有题目再觉得做题顺序,最后一题看了一下,想想也许可以试着暴力(在后面Hogg大牛成功暴力出结果),然后就开始了杯具的第三题,先从模板开始找,找到了几个公式,发现竟然很短,瞬间暗爽了一下,然后快速开敲,谁知运行之后发现竟然错了。。。。然后开始找错(模板没有用过,也有点担心),然后一直找啊找啊找啊找,最后一次次检查模板,然后把整个模板的过程都自己证明了一遍,角度弧度的转化也想了几遍,还是没有找出结果,就这样一直耗着时间,一定要死磕出来(因为过程还是比较随意的,不需要模拟省赛的过程),然后一直调试,所有结果都被输出了,而且由于给出的样例涉及到了三维的球体,自己手算还是很难的,所以过了很久不得已才手算了样例,可是依旧于事无补。。。知道最后也没有找出bug,看了别人代码才发现是角度转弧度出了错,漏了个PI,我还从不同的角度想了想我有没有转化错误。。。。。坑啊,真有揍死自己的想法。。。。两天后改了成功AC。。。。。。
总结:
果然没有用过的模板还是会有点危险,之后的比赛要慎重选择是否真的要用不熟悉的模板;
计算几何真的比较多细节,而且似乎几次做的都是几何+图论相结合(不知道省赛是不是也会如此),真的需要找多个人结队编程,帮我找错才行,不然到时候怕会栽在这上面;
看来我是需要一个好的状态才能A出题,所以慎重选择主攻的题目,而且在卡题的时候应该做到什么程度适宜,真的要好好研究一番。
附上1003代码,谨记教训:
携程全球数据中心建设
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 725 Accepted Submission(s): 307
为了实现每个数据中心的数据能互通,数据中心之间需要通过光纤连接。为了节约光纤成本,我们计划采用点对点方式来达到最终各个数据中心的数据互通,每个数据中心本身都可以作为数据中转站。做为全球多数据中心设计者,您需要知道最短的光纤总长度,来把所有的数据中心都实现互通。假设地球是个圆球,且表面是平滑的,并且没有任何阻碍物(河流,山脉)。
输入数据是一组数据中心的经纬度
纬度: -90° 到 +90°
经度: -180° 到 +180°
(圆周率pi= 3.14159265358979323846)
第一行,小数D(1≤D≤1,000,000),表面圆球的直径(公里).
第二行,小数L(1≤L≤1,000,000) 光纤总长度 (公里).
第三行,整数C(1≤C≤100) ,表示数据中心的数量.
接下来的C行, 每行有2个形如"X Y"的小数,表示每个数据中心的纬度(-90≤X≤90)和经度 (-180≤Y≤180).
1 /* 2 题解:球面的两点距离+最小生成树 3 */ 4 #include <cstdio> 5 #include <cmath> 6 #include <cstring> 7 8 #define VERMAX 105 9 #define MAXDOU 30000000.0 10 const double pi= 3.14159265358979323846; 11 12 using namespace std; 13 14 struct point 15 { 16 double x,y,z; 17 }s[105]; 18 19 int n; 20 21 double gra[105][105]; 22 23 double prim(int n) 24 { 25 bool vis[VERMAX]; 26 double low[VERMAX]; // 一直记录着已访问点集中到i点的最小距离 27 int pos = 0; // 随意选取开始的结点位置 28 memset(vis,false,sizeof(vis)); 29 vis[pos] = true; 30 31 double ret = 0; 32 for(int i=0; i<n; i++) // 初始化 33 low[i] = gra[pos][i]; 34 for(int i=1; i<n; i++) // n-1次求解出剩余的n-1个结点 35 { 36 double min = MAXDOU; 37 for(int j=0; j<n; j++) // 该点集从1开始,共有n个点 38 { 39 if (!vis[j] && low[j] < min) 40 { 41 min = low[j]; 42 pos = j; 43 } 44 } 45 ret += min; 46 vis[pos] = true; 47 for(int j=0; j<n; j++) 48 if (!vis[j] && low[j] > gra[pos][j]) 49 low[j] = gra[pos][j]; 50 } 51 return ret; 52 } 53 54 int main(void) 55 { 56 int t; 57 scanf("%d",&t); 58 while (t--) 59 { 60 double R,l; 61 scanf("%lf%lf%d",&R,&l,&n); 62 R /= 2.0; 63 for(int i=0; i<n; i++) 64 { 65 double lambda,phi; 66 scanf("%lf%lf",&phi,&lambda); 67 phi = phi * pi / 180.0; 68 lambda = lambda * pi / 180.0; 69 s[i].x = cos(phi)*cos(lambda); 70 s[i].y=cos(phi)*sin(lambda); 71 s[i].z=sin(phi); 72 } 73 74 for(int i=0; i<n; i++) 75 for(int j=0; j<n; j++) 76 gra[i][j] = MAXDOU; 77 78 for(int i=0; i<n; i++) 79 for(int j=i+1; j<n; j++) 80 { 81 double A = acos(s[i].x * s[j].x + s[i].y * s[j].y + s[i].z * s[j].z); 82 gra[i][j] = A*R; 83 gra[j][i] = A*R; 84 } 85 double c = prim(n); 86 if (c <= l) 87 printf("Y\n"); 88 else 89 printf("N\n"); 90 } 91 return 0; 92 }