首页 > 其他 > 详细

2014编程之美初赛第一场

时间:2014-04-20 14:07:28      阅读:477      评论:0      收藏:0      [点我收藏+]

题目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

解题思路:

为了方便,我们可以用stringstream字符串流进行string流的读入。

我们需要用long double避免double不够位数的问题。

格式输出:

cout<<setiosflags(ios::fixed)<<setprecision(2)<<ans<<"px"<<endl;

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <set>
#include <map>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <complex>
#include <fstream>
#include <iostream>
#include <algorithm>
#include<iomanip>
 
using namespace std;
 
typedef long long ll;
typedef unsigned long long ull;
 
#define debug puts("yejinru")
#define rep(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define foreach(i,vec) for(int i=0;i<(int)vec.size();i++)
#define pb push_back
#define RD(n) scanf("%d",&n)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w)
#define All(vec) vec.begin(),vec.end()
#define MP make_pair
#define PII pair<int,int>
#define PQ priority_queue
#define cmax(x,y) x = max(x,y)
#define cmin(x,y) x = min(x,y)
#define Clear(x) memset(x,0,sizeof(x))
#define lson rt<<1
#define rson rt<<1|1
#define SZ(x) x.size()
 
/*
 
#pragma comment(linker, "/STACK:1024000000,1024000000")
 
int ssize = 256 << 20; // 256MB
char *ppp = (char*)malloc(ssize) + ssize;
__asm__("movl %0, %%esp\n" :: "r"(ppp) );
 
*/
 
char IN;
bool NEG;
inline void Int(int &x){
    NEG = 0;
    while(!isdigit(IN=getchar()))
        if(IN==‘-‘)NEG = 1;
    x = IN-‘0‘;
    while(isdigit(IN=getchar()))
        x = x*10+IN-‘0‘;
    if(NEG)x = -x;
}
inline void LL(ll &x){
    NEG = 0;
    while(!isdigit(IN=getchar()))
        if(IN==‘-‘)NEG = 1;
    x = IN-‘0‘;
    while(isdigit(IN=getchar()))
        x = x*10+IN-‘0‘;
    if(NEG)x = -x;
}
 
/******** program ********************/
 
long double in(string a){
    int id = 1;
    if( !isdigit(a[ a.size()-2 ]) )
        id = 2;
    stringstream ccin(a.substr(0,a.size()-id));
    long double d;
    ccin>>d;
    if(id==1)
        d *= 1000;
    else{
        id = a.size()-2;
        if(a[id]==‘d‘)
            d *= 100;
        else if(a[id]==‘c‘)
            d *= 10;
        else if(a[id]==‘m‘)
            d *= 1;
        else if(a[id]==‘u‘)
            d *= 0.001;
        else
            d /= 1000*1000;
    }
    return d;
}
 
int main(){
 
#ifndef ONLINE_JUDGE
    freopen("sum.in","r",stdin);
    //freopen("sum.out","w",stdout);
#endif
 
    int ncase,cnt = 0;
    RD(ncase);
    while(ncase--){
        string a,b,c;
        cin>>a>>b>>c;
        long double x = in(a);
        long double y = in(b);
        stringstream dd(c.substr(0,c.size()-2));
        long double z;
        dd>>z;
        long double ans = x/y*z;
        printf("Case %d: ",++cnt);
        cout<<setiosflags(ios::fixed)<<setprecision(2)<<ans<<"px"<<endl;
    }
 
    return 0;
}

 

  

 

 


题目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


比赛时想到正解前,交了一发爆搜,最后大数据都能过,数据也够弱的,囧。

后来在比赛中想到如下思路,最后也A了。

解题思路如下:

首先遍历整棵树,记录下每个节点的高度。

对于询问(x,l,r,delta),我们把该操作(l,r,delta)放进vector[x]中。

最后,我们遍历一遍整棵树,对于节点x,我们用差分数列、树状数组或线段树进行维护。

差分数列维护的话:

先遍历一遍vector[x],把操作(l,r,delta)添加到深度为[l,r]的区间

bubuko.com,布布扣
foreach(i,vec[x]){
    node now = vec[x][i];
    int l = now.l;
    int r = now.r;
    ll val = now.val;
    a[l] += val;
    a[r+1] -= val;
}
bubuko.com,布布扣

因为是dfs,所以递归到下一层时,直接累和即为当前节点的值,累和: 

a[depth] += a[depth-1];

然后递归遍历x节点的子节点

消除当前节点对其他非子节点的影响,最后把加上的给减掉:

bubuko.com,布布扣
a[depth] = (a[depth]-a[depth-1]+3LL*MOD)%MOD;
foreach(i,vec[x]){
    node now = vec[x][i];
    int l = now.l;
    int r = now.r;
    ll val = now.val;
    a[l] -= val;
    a[r+1] += val;
}
bubuko.com,布布扣

最后代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#include <set>
#include <map>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <complex>
#include <fstream>
#include <iostream>
#include <algorithm>
#include<iomanip>
 
using namespace std;
 
typedef long long ll;
typedef unsigned long long ull;
 
#define debug puts("yejinru")
#define rep(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define foreach(i,vec) for(int i=0;i<(int)vec.size();i++)
#define pb push_back
#define RD(n) scanf("%d",&n)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w)
#define All(vec) vec.begin(),vec.end()
#define MP make_pair
#define PII pair<int,int>
#define PQ priority_queue
#define cmax(x,y) x = max(x,y)
#define cmin(x,y) x = min(x,y)
#define Clear(x) memset(x,0,sizeof(x))
#define lson rt<<1
#define rson rt<<1|1
#define SZ(x) x.size()
 
/*
 
#pragma comment(linker, "/STACK:1024000000,1024000000")
 
int ssize = 256 << 20; // 256MB
char *ppp = (char*)malloc(ssize) + ssize;
__asm__("movl %0, %%esp\n" :: "r"(ppp) );
 
*/
 
char IN;
bool NEG;
inline void Int(int &x){
    NEG = 0;
    while(!isdigit(IN=getchar()))
        if(IN==‘-‘)NEG = 1;
    x = IN-‘0‘;
    while(isdigit(IN=getchar()))
        x = x*10+IN-‘0‘;
    if(NEG)x = -x;
}
inline void LL(ll &x){
    NEG = 0;
    while(!isdigit(IN=getchar()))
        if(IN==‘-‘)NEG = 1;
    x = IN-‘0‘;
    while(isdigit(IN=getchar()))
        x = x*10+IN-‘0‘;
    if(NEG)x = -x;
}
 
/******** program ********************/
 
const int MAXN = 1e5+5;
 
struct node{
    int l,r;
    ll val;
    node(){}
    node(int _l,int _r,ll _val){
        l = _l;
        r = _r;
        val = _val;
    }
};
 
vector<int> adj[MAXN];
vector< node > vec[MAXN];
 
ll delta[MAXN];
int dep[MAXN];
 
const int MOD =1000000007; // 10^9 + 7
const int MAGIC= 12347;
 
void dfs_init(int x,int d){ // 初始化每个节点的深度
    dep[x] = d;
    foreach(i,adj[x])
        dfs_init(adj[x][i],d+1);
}
 
ll a[MAXN];
 
void dfs(int x,int depth){
    foreach(i,vec[x]){
        node now = vec[x][i];
        int l = now.l;
        int r = now.r;
        ll val = now.val;
        a[l] += val; // 添加
        a[r+1] -= val;
    }
    a[depth] = (a[depth]+a[depth-1]+3LL*MOD)%MOD; // 差分数列
    delta[x] = a[depth];
    foreach(i,adj[x])
        dfs(adj[x][i],depth+1);
    a[depth] = (a[depth]-a[depth-1]+3LL*MOD)%MOD;
    foreach(i,vec[x]){
        node now = vec[x][i];
        int l = now.l;
        int r = now.r;
        ll val = now.val;
        a[l] -= val; // 消除对后面影响
        a[r+1] += val;
    }
}
 
int main(){
 
#ifndef ONLINE_JUDGE
    freopen("sum.in","r",stdin);
    //freopen("sum.out","w",stdout);
#endif
 
    int ncase,cnt = 0;
    RD(ncase);
    while(ncase--){
        printf("Case %d: ",++cnt);
        int n,pa,q;
        RD(n);
        rep1(i,n){
            adj[i].clear();
            vec[i].clear();
        }
        memset(delta,0,sizeof(delta));
        for(int i=2;i<=n;i++){
            RD(pa);
            adj[pa].pb(i);
        }
 
        dfs_init(1,1);
 
        RD(q);
        int l,r,x,d;
        while(q--){
            RD4(x,l,r,d);
            vec[x].pb( node(l,r,d) );
        }
        memset(a,0,sizeof(a));
        dfs(1,1);
 
        ll ans = 0;
        rep1(i,n)
            ans = (ans*MAGIC+delta[i]+3LL*MOD)%MOD;
        cout<<ans<<endl;
    }
 
    return 0;
}

  

 

 


 

题目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

 

解题思路:

 三分,跟去年编程之美这题2013編程之美 集会 三分基本一样。注意下迭代次数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <stack>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include<iomanip>
 
using namespace std;
 
typedef long long ll;
typedef unsigned long long ull;
 
#define lx(x) (x<<1)
#define rx(x) (x<<1|1)
#define debug puts("here")
#define rep(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define foreach(i,vec) for(unsigned i=0;i<vec.size();i++)
#define pb push_back
#define RD(n) scanf("%d",&n)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w)
 
/******** program ********************/
 
const int MAXN = 1e5+5;
const int INF = 1e8;
 
struct node{
    double x,y;
}p[MAXN];
int n;
 
long double dis(long double x,long double y){
    return sqrt( x*x+y*y );
}
 
long double cal(long double now){
    long double tmp = 0;
    rep(i,n)
        tmp += dis(p[i].x-now,p[i].y);
    return tmp;
}
 
int main(){
 
#ifndef ONLINE_JUDGE
    freopen("sum.in","r",stdin);
    //freopen("sum.out","w",stdout);
#endif
 
    int ncase;
    RD(ncase);
    rep1(Ncase,ncase){
        printf("Case %d: ",Ncase);
        RD(n);
 
        long double L = INF,R = -INF;
        rep(i,n){
            scanf("%lf%lf",&p[i].x,&p[i].y);
            L = min(L,(long double)p[i].x);
            R = max(R,(long double)p[i].x);
        }
        long double l = 0,r = 1;
        long double px1,px2;
        rep(step,50){
            long double m1 = (2*l+r)/3;
            long double m2 = (l+2*r)/3;
 
            px1 = L*(1-m1)+R*m1;
            px2 = L*(1-m2)+R*m2;
 
            long double tmp = cal(px1);
            long double ret = cal(px2);
 
            if(tmp>ret)
                l = m1;
            else
                r = m2;
        }
 
        if(px1<0&&fabs(px1)<1e-9) // 判斷是否會出現-0.000000
            px1 *= -1.0;
        cout<<setiosflags(ios::fixed)<<setprecision(8)<<px1<<endl;
    }
 
    return 0;
}

  

 

2014编程之美初赛第一场,布布扣,bubuko.com

2014编程之美初赛第一场

原文:http://www.cnblogs.com/yejinru/p/3675218.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!