2013年福建省程序设计热身赛

来源:互联网 发布:淘宝客返利源码 编辑:程序博客网 时间:2024/04/29 19:32

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

A. Easy Problem

       这题是special judge,即答案不唯一的题。题意是输入一个大于4的正整数N,然后让你输出3个比N小的数。一种解法是不管N,全部输出1 2 3。

       举办方出这题是为了提醒我们明日的正赛会有这样的special judge题。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

B. Number lengths (FOJ1050)

       题意:输入N,输出N的阶乘是几位数。

       思路:用以10为底的对数运算,能计算一个数是几位数(好好思考为什么)。而对数内部的乘法,可以拆开变成加法运算。(以下代码用GNU C++提交)

#include <cstdio>#include <cmath>using namespace std;int main() {int n;while (scanf("%d", &n) != EOF) {double ans = 1; for (int i = 2; i <= n; i++) ans += log10(i);printf("%d\n", int(ans));}return 0;}

       这样的代码已经能AC了,不过用时78ms。看到有人0ms AC,说明还是能再优化的。见斯特林公式。公式两边同取对数,注意代码中对公式的稍许变化,避免了sqrt运算和提高运算精度。

#include <cstdio>#include <cmath>using namespace std;const double PI = atan(1.0)*4;int main() {int n;while (scanf("%d", &n) != EOF) {int ans = (int)((n*log(n)-n+0.5*log(2*n*PI))/log(10.0))+1;printf("%d\n", ans);}return 0;}
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
C. 土地划分(FOJ1015)

       题意:在一个矩形土地里用L条线段划分,问能划分出多少块土地。

       思路:首先要推导出土地数只跟矩形内的交点个数有关。想想看,L条线段如果互不相交(端点相交不算,以下均如此计算),则可以划分出L+1块土地。又线段间每产生一个交点,就多划分出一份土地。所以土地总数就是L+1+交点数。

       故接下来的难点是如何通过两个线段的端点(点a1,点a2,点b1,点b2),来判断线段a与b是否相交。这里可以用快速排斥和跨立实验。更简单的,不用管那么多原理,计算几何题本来就需要经常套用模板求解,在大白书(刘汝佳的《算法竞赛入门经典——训练指南》第4章),有很多优秀的模板,包括判断两线段是否“规范相交”的SegmentProperIntersection函数。下面的代码从第4至第19行是相应的计算几何模板(实际刷题都是整套模板贴的,模板很长,这里为了简洁,只留下必须的内容),故主函数非常简单,只要每得到一个新的线段,就跟之前的所有线段比较,累加相交次数即可。

#include <iostream>#include <cmath>using namespace std;const double eps = 1e-10;int dcmp(double x) {if(fabs(x)<eps) return 0; else return x<0?-1:1;}struct Point{double x, y;Point(double a=0, double b=0):x(a),y(b) { }};typedef Point Vector;Vector operator - (Point A, Point B) { return Vector(A.x-B.x, A.y-B.y); }double Cross(Vector A, Vector B) { return A.x*B.y-A.y*B.x; }bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2) {double c1 = Cross(a2-a1,b1-a1), c2 = Cross(a2-a1,b2-a1),   c3 = Cross(b2-b1,a1-b1), c4 = Cross(b2-b1,a2-b1);return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;}int main() {Point P[60];int w, h, L, i, j, ans;while (cin >> w >> h, w&&h) {cin >> L >> P[0].x >> P[0].y;ans = L+1;for (i = 1; i <= L; i++) {cin >> P[i].x >> P[i].y;for (j = 1; j < i; j++) {ans += SegmentProperIntersection(P[j-1],P[j],P[i-1],P[i]);}}cout << ans << endl;}return 0;}
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

D. Key problem(FOJ1692)
       这题我之前的一篇博客整理的很好很详细了:FOJ 1692 Key problem


0 0
原创粉丝点击