描述
一般來說,我們採用針孔相機模型,也就是認爲它用到的是小孔成像原理。
在相機座標系下,一般來說,我們用到的單位長度,不是“米”這樣的國際單位,而是相鄰 像素的長度。而焦距在相機座標系中的大小,是在圖像處理領域的一個非常重要的物理 量。
假設我們已經根據相機參數,得到鏡頭的物理焦距大小(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)
解析:
感覺這個題目可能需要用 java 的 BigDecimal 高精度計算,不過,看到 20 分的基礎上,樓 主果斷沒有用 BigDecimal
cin到string和double裏竟然可以這麼用!
//source here
#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;
int main(){
int icase;
cin>>icase;
double x,y,z;
string a,b,c;
for(int i= 1; i<= icase; ++i){
cin>>x>>a>>y>>b>>z>>c;
if(a=="m"){
x*=1000;
}else if(a=="dm"){
x*=100;
}else if(a=="cm"){
x*=10;
}else if(a=="um"){
x/=1000;
}else if(a=="nm"){
x/=1000000;
}
if(b=="m"){
y*=1000;
}else if(b=="dm"){
y*=100;
}else if(b=="cm"){
y*=10;
}else if(b=="um"){
y/=1000;
}else if(b=="nm"){
y/=1000000;
}
double tt= x*z/y;
printf("Case %d: %.2lfpx\n",i, tt);
}
}
第二題:
描述
有一個 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
分析:
果斷地先根據根,進行廣度遍歷,求出層次,然後修改值的時候也是層次遍歷。
代碼:
//source here
#include <iostream>
#include <vector>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <queue>
using namespace std;
const int NODE_COUNT= 100001;
vector<int> child[NODE_COUNT];
long long val[NODE_COUNT];
long long parent[NODE_COUNT];
int level[NODE_COUNT];
int node;
long long MOD =1000000007; // 10^9 + 7
long long MAGIC= 12347;
void BuildLevel();
void Change(int u,int r,int l, int delta);
long long hash();
int main(){
int icase;
cin>>icase;
int c;
for(int i= 1; i<= icase; ++i){
scanf("%d",&node);
memset(val,0,NODE_COUNT*sizeof(int));
for(int l= 0; l< node; ++l){//empty child
child[l].clear();
}
level[0]= 1;
for(int l= 1; l< node; ++l){
scanf("%d",&c);
--c;
parent[l]=c;
child[c].push_back(l);
}
BuildLevel();
int r,l,delta,u;
int x;
scanf("%d",&x);
while(x--){
cin>>u>>l>>r>>delta;
--u;
Change(u,l,r,delta);
}
cout<<"Case "<<i<<": "<<::hash()<<endl;
}
}
void Change(int u,int l,int r, int delta){
queue<int> q;
q.push(u);
int now;
while(!q.empty()){
now= q.front();
vector<int>& lhs= child[now];
q.pop();
if(level[now]>= l && level[now]<= r){//[l,r]
val[now]+=delta;
}else if(level[now]>r){
continue;
}
for(int i= 0; i< lhs.size();++i){
q.push(lhs[i]);
}
}
}
long long hash(){
long long s= 0;
for(int i= 0; i< node; ++i){
s= (s*MAGIC+val[i])%MOD;
}
return s;
}
void BuildLevel(){
queue<int> q;
level[0]= 1;
q.push(0);
int now;
while(!q.empty()){
now= q.front();
q.pop();
vector<int>& lhs= child[now];
for(int i= 0; i< lhs.size(); ++i){
level[lhs[i]]= level[now]+1;
q.push(lhs[i]);
}
}
}
第三題: 描述
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
解析:
果斷地,求導數,導數爲 0 的值就是我們要求的,我們會發現導數是單調的(導數的導數 大於 0),然後果斷二分。
代碼:
//source here
#include <iostream>
#include <vector>
#include <stdio.h>
#include <utility>
#include <algorithm>
#include <string>
#include <math.h>
using namespace std;
vector<pair<double,double> > point;
const double EPSI= 0.000000001;
bool operator < (const pair<double,double>& lhs, const pair<double,double>& rhs){
return lhs.first< rhs.first;
}
bool Check(double x);
int main(){
int icase;
cin>>icase;
pair<double,double> pt;
int ic;
double l,h,mid;
for(int i= 1; i<= icase; ++i){
cin>>ic;
point.clear();
while(ic--){
cin>>pt.first>>pt.second;
point.push_back(pt);
}
sort(point.begin(),point.end());
l= point[0].first;
h= point[point.size()-1].first;
while(fabs(l-h)>= EPSI){
mid= (l+h)/2;
if(Check(mid)){//>=0
h= mid;
}else{
l= mid;
}
}
printf("Case %d: %.6lf\n",i,mid);
}
}
bool Check(double x){
double sum= 0;
int len= point.size();
double a,b;
for(int i= 0; i< len; ++i){
a= x-point[i].first;
b= sqrt(a*a+(point[i].second*point[i].second));
sum+=a/b;
}
return sum>= 0;
}