编程之美初赛第一场

题目1 : 焦距

时间限制:2000ms
单点时限:1000ms
内存限制:256MB

描述

一般来说,我们采用针孔相机模型,也就是认为它用到的是小孔成像原理。

在相机坐标系下,一般来说,我们用到的单位长度,不是“米”这样的国际单位,而是相邻像素的长度。而焦距在相机坐标系中的大小,是在图像处理领域的一个非常重要的物理量。

假设我们已经根据相机参数,得到镜头的物理焦距大小(focal length),和相机胶片的宽度(CCD width),以及照片的横向分辨率(image width),则具体计算公式为:

Focal length in pixels = (image width in pixels) * (focal length on earth) / (CCD width on earth)

比如说对于Canon PowerShot S100, 带入公式得

Focal length in pixels = 1600 pixels * 5.4mm / 5.27mm = 1639.49 pixels

现在,请您写一段通用的程序,来求解焦距在相机坐标系中的大小。

输入

多组测试数据。首先是一个正整数T,表示测试数据的组数。

每组测试数据占一行,分别为

镜头的物理焦距大小(focal length on earth)

相机胶片的宽度(CCD width on earth)

照片的横向分辨率大小(image width in pixels),单位为px。

之间用一个空格分隔。

输出

每组数据输出一行,格式为“Case X: Ypx”。 X为测试数据的编号,从1开始;Y为焦距在相机坐标系中的大小(focallength in pixels),保留小数点后2位有效数字,四舍五入取整。

数据范围

对于小数据:focal length on earth和CCD width on earth单位都是毫米(mm)

对于大数据:长度单位还可能为米(m), 分米(dm), 厘米(cm), 毫米(mm), 微米(um),纳米(nm)

样例输入
2
5.4mm 5.27mm 1600px
5400um 0.00527m 1600px
样例输出
Case 1: 1639.47px
Case 2: 1639.47px
 1 #include <stdio.h>
 2 #include <string.h>
 3 double cmp(char s[])
 4 {
 5     if(strcmp(s,"mm")==0)
 6         return 1.0;
 7     else if (strcmp(s,"m")==0)
 8         return 1000.0;
 9     else if (strcmp(s,"cm")==0)
10         return 10.0;
11     else if (strcmp(s,"dm")==0)
12         return 100.0;
13     else if (strcmp(s,"um")==0)
14         return 0.001;
15     else if (strcmp(s,"nm")==0)
16         return 0.000001;
17 }
18 int main()
19 {
20     int t;
21     scanf("%d",&t);
22     for (int i = 1; i <= t; i++)
23     {
24         double l,w,m;
25         char s1[5],s2[5],s3[5];
26         scanf("%lf%s %lf%s %lf%s",&l,s2,&w,s3,&m,s1);
27         l = l*cmp(s2);
28         w = w*cmp(s3);
29         double ans = m*l/w;
30         printf("Case %d: %.2fpx\n",i,ans);
31     }
32     return 0;
33 }
View Code

 

题目2 : 树

时间限制:4000ms
单点时限:2000ms
内存限制:256MB

描述

有一个N个节点的树,其中点1是根。初始点权值都是0。

一个节点的深度定义为其父节点的深度+1,。特别的,根节点的深度定义为1。

现在需要支持一系列以下操作:给节点u的子树中,深度在l和r之间的节点的权值(这里的深度依然从整个树的根节点开始计算),都加上一个数delta。

问完成所有操作后,各节点的权值是多少。

 

为了减少巨大输出带来的开销,假设完成所有操作后,各节点的权值是answer[1..N],请你按照如下方式计算出一个Hash值(请选择合适的数据类型,注意避免溢出的情况)。最终只需要输出这个Hash值即可。

 

MOD =1000000007; // 10^9 + 7

MAGIC= 12347;

Hash =0;

For i= 1 to N do

    Hash = (Hash * MAGIC + answer[i]) mod MOD;

EndFor 

输入

第一行一个整数T (1 ≤ T ≤ 5),表示数据组数。

接下来是T组输入数据,测试数据之间没有空行。

每组数据格式如下:

第一行一个整数N (1 ≤ N ≤ 105),表示树的节点总数。

接下来N - 1行,每行1个数,a (1 ≤ a ≤ N),依次表示2..N节点的父亲节点的编号。

接下来一个整数Q(1 ≤ Q ≤ 105),表示操作总数。

接下来Q行,每行4个整数,u, l, r, delta (1 ≤ u ≤ N, 1 ≤ l ≤ r ≤ N, -109 ≤ delta ≤ 109),代表一次操作。

输出

对每组数据,先输出一行“Case x: ”,x表示是第几组数据,然后接这组数据答案的Hash值。

数据范围

小数据:1 ≤ N, Q ≤ 1000

大数据:1 ≤ N, Q ≤ 105

样例解释

点1的子树中有1,2,3三个节点。其中深度在2-3之间的是点2和点3。

点2的子树中有2,3两个节点。其中没有深度为1的节点。

所以,执行完所有操作之后,只有2,3两点的权值增加了1。即答案是0 1 1。再计算对应的Hash值即可.

样例输入
1
3
1
2
2
1 2 3 1
2 1 1 1
样例输出
Case 1: 12348
 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <vector>
 4 using namespace std;
 5 const int N=100005;
 6 const long long MOD=1000000007;
 7 vector<int>v[N];
 8 int deg[N],ans[N];
 9 int n;
10 void dfs(int u,int d)//搜索处理每一点的度
11 {
12     deg[u] = d;
13     for (int i = 0; i < v[u].size(); i++)
14     {
15         dfs(v[u][i],d+1);
16     }
17 }
18 void dfs2(int u,int l,int r,int c)//搜索改变区间[l,r]的度
19 {
20     if (deg[u] > r)
21         return;
22     if (deg[u]>=l)
23         ans[u]+=c;
24     for (int i = 0; i < v[u].size(); i++)
25     {
26         dfs2(v[u][i],l,r,c);
27     }
28 }
29 long long hash()
30 {
31     long long Hash = 0;
32     int MAGIC= 12347;
33     for (int i = 1; i <= n; i++)
34         Hash = (Hash * MAGIC + ans[i]) % MOD;
35     return Hash;
36 }
37 int main()
38 {
39     int t,o = 0;
40     scanf("%d",&t);
41     while(t--)
42     {
43         o++;
44         int x;
45         scanf("%d",&n);
46         for (int i = 0; i <= n; i++)
47             v[i].clear();
48         memset(deg,0,sizeof(deg));
49         memset(ans,0,sizeof(ans));
50         for (int i = 2; i <= n; i++)
51         {
52             scanf("%d",&x);
53             v[x].push_back(i);
54         }
55         dfs(1,1);
56         int Q;
57         scanf("%d",&Q);
58         int u,l,r,c;
59         long long Hash;
60         while(Q--)
61         {
62             scanf("%d%d%d%d",&u,&l,&r,&c);
63             dfs2(u,l,r,c);
64             Hash = hash();
65         }
66         printf("Case %d: %lld\n",o,Hash);
67     }
68     return 0;
69 }
View Code

题目3 : 活动中心

时间限制:12000ms
单点时限:6000ms
内存限制:256MB

描述

A市是一个高度规划的城市,但是科技高端发达的地方,居民们也不能忘记运动和锻炼,因此城市规划局在设计A市的时候也要考虑为居民们建造一个活动中心,方便居住在A市的居民们能随时开展运动,锻炼强健的身心。

城市规划局希望活动中心的位置满足以下条件:

1. 到所有居住地的总距离最小。

2. 为了方便活动中心的资源补给和其他器材的维护,活动中心必须建设在A市的主干道上。

为了简化问题,我们将A市摆在二维平面上,城市的主干道看作直角坐标系平的X轴,城市中所有的居住地都可以看成二维平面上的一个点。

现在,A市的城市规划局希望知道活动中心建在哪儿最好。

输入

第一行包括一个数T,表示数据的组数。

接下来包含T组数据,每组数据的第一行包括一个整数N,表示A市共有N处居住地

接下来N行表示每处居住地的坐标。

输出

对于每组数据,输出一行“Case X: Y”,其中X表示每组数据的编号(从1开始),Y表示活动中心的最优建造位置。我们建议你的输出保留Y到小数点后6位或以上,任何与标准答案的绝对误差或者相对误差在10-6以内的结果都将被视为正确。

 

数据范围

小数据:1 ≤ T ≤ 1000, 1 ≤ N ≤ 10

大数据:1 ≤ T ≤ 10, 1 ≤ N ≤ 105

对于所有数据,坐标值都是整数且绝对值都不超过106

样例解释

样例1:活动中心的最优建造位置为(1.678787, 0)

样例输入
1
3
1 1
2 2
3 3
样例输出
Case 1: 1.678787
 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <math.h>
 4 #include <iostream>
 5 #include <algorithm>
 6 using namespace std;
 7 const int INF=1<<28;
 8 const int N=100005;
 9 const double eps=1e-8;
10 int n;
11 struct node
12 {
13     double x,y;
14 }f[N];
15 int max = INF;
16 double dis(double x,double y,double xx)
17 {
18     return sqrt((x-xx)*(x-xx)+y*y);
19 }
20 double ternarySearch(double l,double r)//三分
21 {
22     while(r-l>eps)
23     {
24         double sum1 = 0,sum2 = 0;
25         double ll=(2*l+r)/3;
26         double rr=(l+2*r)/3;
27         for (int i = 1;i <= n; i++)
28         sum1+=dis(f[i].x,f[i].y,ll);
29         for (int i = 1;i <= n; i++)
30         sum2+=dis(f[i].x,f[i].y,rr);
31         if (sum1 > sum2)
32         l = ll;
33         else
34         r = rr;
35 
36     }
37     return l;
38 }
39 int main()
40 {
41     int t;
42     int o = 0;
43     printf("%d\n",INF);
44     scanf("%d",&t);
45     while(t--)
46     {
47         o++;
48         scanf("%d",&n);
49         double l = INF,r = -INF;
50         for (int i = 1;i <= n; i++)
51         {
52             scanf("%lf%lf",&f[i].x,&f[i].y);
53             if (l > f[i].x)
54             l = f[i].x;
55             if (r < f[i].y)
56             r = f[i].y;
57         }
58         double ans = ternarySearch(l,r);
59         printf("Case %d: %.7f\n",o,ans);
60 
61     }
62     return 0;
63 }
View Code

 

posted @ 2014-04-20 23:43  N_ll  阅读(171)  评论(0编辑  收藏  举报