微软编程之美部分解题报告.docx
- 文档编号:27895797
- 上传时间:2023-07-06
- 格式:DOCX
- 页数:23
- 大小:24.21KB
微软编程之美部分解题报告.docx
《微软编程之美部分解题报告.docx》由会员分享,可在线阅读,更多相关《微软编程之美部分解题报告.docx(23页珍藏版)》请在冰豆网上搜索。
微软编程之美部分解题报告
微软编程之美2014初赛第一场解题报告
题目1:
焦距
时间限制:
2000ms
单点时限:
1000ms
内存限制:
256MB
描述
一般来说,我们采用针孔相机模型,也就是认为它用到的是小孔成像原理。
在相机坐标系下,一般来说,我们用到的单位长度,不是“米”这样的国际单位,而是相邻像素的长度。
而焦距在相机坐标系中的大小,是在图像处理领域的一个非常重要的物理量。
假设我们已经根据相机参数,得到镜头的物理焦距大小(focallength),和相机胶片的宽度(CCDwidth),以及照片的横向分辨率(imagewidth),则具体计算公式为:
Focallengthinpixels=(imagewidthinpixels)*(focallengthonearth)/(CCDwidthonearth)
比如说对于CanonPowerShotS100,带入公式得
Focallengthinpixels=1600pixels*5.4mm/5.27mm=1639.49pixels
现在,请您写一段通用的程序,来求解焦距在相机坐标系中的大小。
输入
多组测试数据。
首先是一个正整数T,表示测试数据的组数。
每组测试数据占一行,分别为
镜头的物理焦距大小(focallengthonearth)
相机胶片的宽度(CCDwidthonearth)
照片的横向分辨率大小(imagewidthinpixels),单位为px。
之间用一个空格分隔。
输出
每组数据输出一行,格式为“CaseX:
Ypx”。
X为测试数据的编号,从1开始;Y为焦距在相机坐标系中的大小(focallengthinpixels),保留小数点后2位有效数字,四舍五入取整。
数据范围
对于小数据:
focallengthonearth和CCDwidthonearth单位都是毫米(mm)
对于大数据:
长度单位还可能为米(m),分米(dm),厘米(cm),毫米(mm),微米(um),纳米(nm)
样例输入
2
5.4mm5.27mm1600px
5400um0.00527m1600px
样例输出
Case1:
1639.47px
Case2:
1639.47px
窗体顶端
viewsource
01
//sourcehere
02
//题目1:
焦距bykryptosx
03
//字符串读入,识别长度单位,然后转换单位,计算即可。
04
//注意输出时小数点精确
05
#include
06
#include
07
#include
08
#include
09
#include
10
#include
11
#include
12
#include
13
#include
14
#include
15
#include
16
#include
17
#include
18
usingnamespacestd;
19
doublechange(charas[])
20
{
21
intlen=strlen(as);
22
doubleans=0;
23
if(as[len-1]=='m'&&as[len-2]=='m')//mm
24
{
25
as[len-2]='';
26
sscanf(as,"%lf",&ans);
27
}
28
elseif(as[len-1]=='m'&&as[len-2]=='n')//nm
29
{
30
as[len-2]='';
31
sscanf(as,"%lf",&ans);
32
ans*=0.000001;
33
}
34
elseif(as[len-1]=='m'&&as[len-2]=='u')//um
35
{
36
as[len-2]='';
37
sscanf(as,"%lf",&ans);
38
ans*=0.001;
39
}
40
elseif(as[len-1]=='m'&&as[len-2]=='c')//cm
41
{
42
as[len-2]='';
43
sscanf(as,"%lf",&ans);
44
ans*=10;
45
}
46
elseif(as[len-1]=='m'&&as[len-2]=='d')//dm
47
{
48
as[len-2]='';
49
sscanf(as,"%lf",&ans);
50
ans*=100;
51
}
52
else //m
53
{
54
as[len-1]='';
55
sscanf(as,"%lf",&ans);
56
ans*=1000;
57
}
58
returnans;
59
}
60
intmain()
61
{
62
intT;
63
cin>>T;
64
intjs=0;
65
charas[100],bs[100];
66
doublea,b,c,ans;
67
while(T--)
68
{
69
scanf("%s%s%lfpx",as,bs,&c);
70
a=change(as);
71
b=change(bs);
72
ans=c*a/b;
73
printf("Case%d:
%.2lfpxn",++js,ans);
74
}
75
return0;
76
}
题目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;
Fori=1toNdo
Hash=(Hash*MAGIC+answer[i])modMOD;
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),代表一次操作。
输出
对每组数据,先输出一行“Casex:
”,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。
即答案是011。
再计算对应的Hash值即可。
样例输入
1
3
1
2
2
1231
2111
样例输出
Case1:
12348
viewsource
01
//sourcehere
02
//题目2:
树bykryptosx
03
//直接用vector建树,dfs进行遍历解决。
比较暴力的方法,没想到能过大数据。
04
//最后一分钟提交的,能交上真是奇迹啊。
05
#include
06
#include
07
#include
08
#include
09
#include
10
#include
11
#include
12
#include
13
#include
14
#include
15
#include
16
#include
17
#include
18
usingnamespacestd;
19
structNode
20
{
21
intdeep;
22
longlongval;
23
}p[100100];
24
vector
25
voidxdfs(intx,intdeep)
26
{
27
p[x].deep=deep;
28
p[x].val=0;
29
intlen=mpt[x].size();
30
for(inti=0;i 31 { 32 xdfs(mpt[x][i],deep+1); 33 } 34 return; 35 } 36 voiddfs(intu,intl,intr,intd) 37 { 38 if(p[u].deep>=l&&p[u].deep<=r) 39 { 40 p[u].val+=d; 41 } 42 intlen=mpt[u].size(); 43 for(inti=0;i 44 { 45 dfs(mpt[u][i],l,r,d); 46 } 47 return; 48 } 49 intmain(void) 50 { 51 intT,n,x,js=0; 52 cin>>T; 53 while(T--) 54 { 55 memset(mpt,0,sizeofmpt); 56 memset(p,0,sizeofp); 57 cin>>n; 58 for(inti=2;i<=n;i++) 59 { 60 scanf("%d",&x); 61 mpt[x].push_back(i); 62 } 63 intm; 64 cin>>m; 65 xdfs(1,1); 66 intu,l,r,d; 67 while(m--) 68 { 69 scanf("%d%d%d%d",&u,&l,&r,&d); 70 dfs(u,l,r,d); 71 } 72 longlongans=0; 73 longlongMOD=1000000007;//10^9+7 74 longlongMAGIC=12347; 75 for(inti=1;i<=n;i++) 76 { 77 ans=(ans*MAGIC+p[i].val)%MOD; 78 } 79 printf("Case%d: %lldn",++js,ans); 80 } 81 return0; 82 } 题目3: 活动中心 时间限制: 12000ms 单点时限: 6000ms 内存限制: 256MB 描述 A市是一个高度规划的城市,但是科技高端发达的地方,居民们也不能忘记运动和锻炼,因此城市规划局在设计A市的时候也要考虑为居民们建造一个活动中心,方便居住在A市的居民们能随时开展运动,锻炼强健的身心。 城市规划局希望活动中心的位置满足以下条件: 1.到所有居住地的总距离最小。 2.为了方便活动中心的资源补给和其他器材的维护,活动中心必须建设在A市的主干道上。 为了简化问题,我们将A市摆在二维平面上,城市的主干道看作直角坐标系平的X轴,城市中所有的居住地都可以看成二维平面上的一个点。 现在,A市的城市规划局希望知道活动中心建在哪儿最好。 输入 第一行包括一个数T,表示数据的组数。 接下来包含T组数据,每组数据的第一行包括一个整数N,表示A市共有N处居住地 接下来N行表示每处居住地的坐标。 输出 对于每组数据,输出一行“CaseX: 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 11 22 33 样例输出 Case1: 1.678787 viewsource 01 //sourcehere 02 //题目3: 活动中心bykryptosx 03 //一开始考虑是否需要暴力什么的,一看数据范围,肯定不可能。 04 //后来考虑是不是可以三分,因为感觉距离和会随着x轴坐标变化而呈现一个 05 //凹形曲线。 所以果断弄个三分的模板啥。 06 //优化了一下范围,因为估计范围一定在最左和最右的点之内。 07 #include 08 #include 09 #include 10 #include 11 #include 12 #include 13 usingnamespacestd; 14 constdoubleeps=1e-8; 15 structnode 16 { 17 doublex,y; 18 }; 19 nodep[10000010]; 20 intT,n; 21 doublemaxm; 22 doubleplay(doublex); 23 doubledis(doublex); 24 intjs=1; 25 intmain() 26 { 27 28 scanf("%d",&T); 29 while(T--) 30 { 31 scanf("%d",&n); 32 doublel=100000010,r=-100000010,m,ml,mr; 33 for(inti=0;i 34 { 35 scanf("%lf%lf",&p[i].x,&p[i].y); 36 l=min(l,p[i].x); 37 r=max(r,p[i].x); 38 } 39 while(fabs(l-r)>eps) 40 { 41 m=(l+r)/2.0; 42 ml=(l+m)/2.0; 43 mr=(m+r)/2.0; 44 if(play(ml)>play(mr)) 45 l=ml; 46 else 47 r=mr; 48 } 49 printf("Case%d: ",js++); 50 printf("%.6lfn",(ml+mr)/2.0); 51 } 52 return0; 53 } 54 doubledis(nodea,nodeb) 55 { 56 doublec=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); 57 returnsqrt(c); 58 } 59 doubleplay(doublex) 60 { 61 doublesum=0.0; 62 nodea; 63 a.x=x; 64 a.y=0; 65 for(inti=0;i 66 { 67 sum+=dis(a,p[i]); 68 } 69 returnsum; 70 } 编程之美2014-资格赛题解 第一题: 树的同构,不过这题不用去求同构,我们总是可以根据深度交叉染色,所以如果B树的最大深度超过1的话,我们一定可以通过交叉染色避免B树出现在A树上。 当B树深度<=1,即一个节点直接连接着几条边这种情况,记其度为xb,这时我们只需寻找A树中度数最大的节点,记其度为xa,我们知道如果(xa+1)/2>=xb那么一定可以从A树中对应节点抠出几条同色的边组成B树。 第二题: 推数学公式。 比较简单。 用到立方和公式和平方和公式。 第三题: 网络流。 把方格图转化为二分图的形式后,我们可以看出这是一个求最小边权覆盖集问题。 不过之前没有做过这类问题,具体参考 构图如下: 添加原点和超级原点,汇点和超级汇点。 超级原点到原点流量为n*m,花费为0; 汇点到超级汇点流量为n*m,花费为0; 左边2*n个点,右边2*m个点。 上方的n,m个点是用来约束覆盖的: 流量为1,费用为负无穷 下方的n,m个点是用来提供边的: 流量为m,n(其实就是无穷),费用为0 从原点到汇点添加流量为n*m,费用为0的边。 构造费用为负无穷,容量为1的n+m条边保证最小费用流一定可以流过这n+m条边,并将剩下的流量通过从源到汇直接连边(流量无穷,费用0)引流走。 可以保证结果的正确性。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 微软 编程 部分 解题 报告