zoukankan      html  css  js  c++  java
  • 2014编程之美初赛第一场

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

    #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
    " :: "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]的区间

    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;
    }

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

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

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

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

    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;
    }

    最后代码如下:

    #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
    " :: "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編程之美 集会 三分基本一样。注意下迭代次数。

    #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;
    }
    

      

  • 相关阅读:
    Linux netstat命令详解
    【转】Jenkins怎么启动和停止服务
    Jenkins权限配置失误后导致登录失败的解决办法
    Linux下查看某一进程所占用内存的方法
    Linux集群配置ntp时间同步服务
    Linux下安装MySQL数据库
    Redis集群的部署
    Linux下安装Nginx服务器
    为Linux服务器设置静态IP的方法
    vSphere Client无法连接到服务器 出现未知错误的解决方法
  • 原文地址:https://www.cnblogs.com/yejinru/p/3675218.html
Copyright © 2011-2022 走看看