第一次写博客,有什么不足之处,请提意见。
题目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<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<algorithm> 6 #include<vector> 7 #include<map> 8 #include<set> 9 #include<cmath> 10 using namespace std; 11 12 double get(char s[]) 13 { 14 double ans; 15 sscanf(s, "%lf", &ans); 16 int len = strlen(s); 17 18 char c = s[len - 2]; 19 if(c == 'd') ans *= 100; 20 else 21 if(c == 'c') ans *= 10; 22 else 23 if(c == 'm') ; 24 else 25 if(c=='u') ans /= 1000; 26 else 27 if(c == 'n') ans /= 1000000; 28 else 29 ans *= 1000; 30 31 return ans; 32 } 33 int main() 34 { 35 int T; 36 scanf("%d", &T); 37 for(int cas = 1; cas <= T; cas++) 38 { 39 char s[1000]; 40 41 scanf("%s", s); 42 double focal = get(s); 43 44 scanf("%s", s); 45 double ccd = get(s); 46 47 scanf("%s", s); 48 double image; 49 sscanf(s, "%lf", &image); 50 51 //printf("{%lf %lf %lf}\n", focal, ccd, image); 52 double ans = image * focal / ccd; 53 printf("Case %d: %.2lfpx\n", cas, ans); 54 } 55 return 0; 56 }
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
样例输出
跟树相关的算法,树链剖分、树形dp、欧拉序列。都没用上,该题只需要dfs,然后再用树状数组统计下当前节点的祖先的影响就可以了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<algorithm> 6 #include<vector> 7 #include<map> 8 #include<set> 9 #include<cmath> 10 using namespace std; 11 12 typedef long long ll; 13 const int maxn = 100010; 14 int first[maxn]; 15 struct Arc 16 { 17 int v, next; 18 }arc[maxn]; 19 int first2[maxn]; 20 struct Arc2 21 { 22 int l, delta, next; 23 }query[maxn * 2]; 24 int cnt; 25 int n; 26 ll answer[maxn], sum[maxn]; 27 28 void addQuery(int u, int l, int delta) 29 { 30 query[cnt].l = l; 31 query[cnt].delta = delta; 32 query[cnt].next = first2[u]; 33 first2[u] = cnt++; 34 } 35 36 void add(int i, int delta) 37 { 38 for(; i <= n; i += i & (-i)) 39 sum[i] += delta; 40 } 41 42 ll ask(int i) 43 { 44 ll ans = 0; 45 for(; i > 0; i-= i & (-i)) 46 ans += sum[i]; 47 48 return ans; 49 } 50 51 void dfs(int u, int deep) 52 { 53 // printf("(%d %d)\n", u, deep); 54 for(int i = first2[u]; i + 1; i = query[i].next) 55 { 56 int l = query[i].l, delta = query[i].delta; 57 add(l, delta); 58 } 59 60 answer[u] = ask(deep); 61 for(int i = first[u]; i + 1; i = arc[i].next) 62 { 63 int v = arc[i].v; 64 dfs(v, deep + 1); 65 } 66 67 for(int i = first2[u]; i + 1; i = query[i].next) 68 { 69 int l = query[i].l, delta = query[i].delta; 70 add(l, -delta); 71 } 72 } 73 int solve() 74 { 75 ll MOD =1000000007; // 10^9 + 7 76 ll MAGIC= 12347; 77 ll Hash =0; 78 for(int i= 1; i <= n; i++) 79 Hash = (Hash * MAGIC + answer[i]) % MOD; 80 81 return (int)Hash; 82 } 83 int main() 84 { 85 int T; 86 scanf("%d", &T); 87 for(int cas = 1; cas <= T; cas++) 88 { 89 scanf("%d", &n); 90 for(int i = 1; i <= n; i++) 91 first[i] = first2[i] = -1; 92 93 cnt = 0; 94 for(int i = 2; i <= n; i++) 95 { 96 int fa; 97 scanf("%d", &fa); 98 arc[cnt].v = i; 99 arc[cnt].next = first[fa]; 100 first[fa] = cnt++; 101 } 102 103 int Q; 104 scanf("%d", &Q); 105 cnt = 0; 106 for(int i = 1; i <= Q; i++) 107 { 108 int u, l, r, delta; 109 scanf("%d%d%d%d", &u, &l, &r, &delta); 110 111 addQuery(u, l, delta); 112 addQuery(u, r + 1, -delta); 113 } 114 115 dfs(1, 1); 116 printf("Case %d: %d\n", cas, solve()); 117 } 118 return 0; 119 }
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
刚开始也想不出来。如果是绝对值之和最小,只需要中位数就可以了;如果是使最大距离最小,只需要二分+线段覆盖统计;后来觉得每个点都有个最近距离点,沿着x轴变化,距离之和可能是个凹函数,就想到三分,太久没写,有点抠不出来。可以求导验证
三分需要注意限制次数,不然容易超时。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<algorithm> 6 #include<vector> 7 #include<map> 8 #include<set> 9 #include<cmath> 10 using namespace std; 11 12 double eps = 1e-10; 13 14 int sgn(double x) 15 { 16 return x < -eps ? -1 : x > eps; 17 } 18 19 int n; 20 struct Point 21 { 22 double x, y; 23 void input() 24 { 25 scanf("%lf%lf", &x, &y); 26 27 y *= y; 28 } 29 30 double cal(double xx) 31 { 32 return sqrt(y + (xx - x) * (xx - x)); 33 } 34 }p[100010]; 35 36 double cal(double x) 37 { 38 double ans = 0; 39 for(int i = 0; i < n; i++) 40 ans += p[i].cal(x); 41 42 return ans; 43 } 44 double solve() 45 { 46 double l = 1e100, r = -1e100; 47 for(int i = 0; i < n; i++) 48 { 49 double x = p[i].x; 50 l = min(l, x); 51 r = max(r, x); 52 } 53 54 double x1 = l,x2, x3, x4 = r, ans; 55 for(int i = 0; i <= 100 && sgn(x4 - x1) > 0; i++) 56 { 57 x2 = x1 + (x4 - x1) / 3; 58 x3 = x2 + (x4 - x1) / 3; 59 60 double f2 = cal(x2), f3 = cal(x3); 61 ans = x2; 62 if(sgn(f2 - f3) > 0) 63 x1 = x2; 64 else 65 x4 = x3; 66 } 67 68 return ans; 69 } 70 71 int main() 72 { 73 int T; 74 scanf("%d", &T); 75 for(int cas = 1; cas <=T; cas++) 76 { 77 scanf("%d", &n); 78 for(int i = 0; i < n; i++) 79 p[i].input(); 80 81 printf("Case %d: %.10lf\n", cas, solve()); 82 } 83 return 0; 84 }
View Code
样例输出
-
样例输出
转载于:https://www.cnblogs.com/dango/p/3675259.html