编程之美 2014 初赛第一场

来源:互联网 发布:event js 编辑:程序博客网 时间:2024/04/30 10:03

先上代码。。。

题目解析和测试用例,稍后会给出微软官方的解析

1. 焦距(字符串处理):

/* * main.cpp * *  Created on: 2014-4-19 *      Author: zy */#include<iostream>#include<iostream>#include<string>#include<cstring>#include<vector>#include<cstdlib>#include<iomanip> //setprecision控制小数点的个数using namespace std;double change(string s,int length){char a[100]={0};double mul;//用switch处理比if语句,可以节省很多代码,,,switch(s[length-2]) {case 'd': mul = 1e8;s[length-2] = 0;break;case 'c': mul = 1e7;s[length-2] = 0;break;case 'm': mul = 1e6;s[length-2] = 0;break;case 'u': mul = 1e3;s[length-2] = 0;break;case 'n':case 'p': mul = 1; s[length-2] = 0;break;default : mul = 1e9;s[length-1] = 0;}s.copy(a,s.size(),0);   //不要这句话,下面的字符串到double型会报错,或者从string 到char *强制转化下double ret = atof(a);return ret*mul;}int main(){int T;cin >> T;double result=0;int count = 1;string s1,s2,s3;while(T--) {//输入数据,做相应替换:5.4mm 5.27mm 1600pxcin >> s1 >> s2 >> s3;double x,y,z;//获取字符串中的单位,并进行转换(nm,不用有除法)x = change(s1,s1.size());y = change(s2,s2.size());z = change(s3,s3.size());result = z*x/y;//输出结果cout<<"Case "<< count<<": ";cout << fixed << setprecision(2) << result<< "px" <<endl;count++;}result = 0;}

2. 树(同学写的,菜鸟表示不太会,,,注释是我加的,大家先不要看注释,直接看代码,代码我还没理解透):

#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<string>#include<map>#include<iostream>#include<sstream>#include<queue>using namespace std;#define ll long longconst ll mod=1000000007LL,MG=12347LL;int T,cas=0,N,st[100005],e,h[100005];vector<int> L[100005],R[100005],del[100005];ll tr[100005],num[100005];struct EG{    int v,nx;}eg[100005];void add(int u,int v){    eg[e].v=v;eg[e].nx=st[u];st[u]=e++;}void update(int k,int v){    v%=mod;    for(;k<=N;k+=k&-k)    {        tr[k]+=v;        if(tr[k]>=mod)tr[k]-=mod;    }}ll read(int k){    ll ret=0;    for(;k;k-=k&-k)    {        ret+=tr[k];        if(ret>=mod)ret-=mod;    }    return ret;}//根据每个节点的度数和一个公式,来计算最终输出的结果ll cal(){    ll ans=0;    for(int i=1;i<=N;i++)    {        ans=(ans*MG+num[i])%mod;    }    return ans;}//dfs--深度优先算法,u:节点,hh:深度void dfs(int u,int hh){    h[u]=hh;    int sz=L[u].size();    for(int i=0;i<sz;i++)    {        update(L[u][i],del[u][i]);        update(R[u][i]+1,-del[u][i]);        //printf("%d - %d %d %d\n",u,L[u][i],R[u][i],del[u][i]);    }    //printf("%d %d\n",u,h[u]);    num[u]=read(h[u]);    for(int i=st[u];~i;i=eg[i].nx)    {        int v=eg[i].v;        dfs(v,hh+1);    }    for(int i=0;i<sz;i++)    {        update(L[u][i],-del[u][i]);        update(R[u][i]+1,del[u][i]);    }}int main(){    scanf("%d",&T);    while(T--)    {        //N个节点        scanf("%d",&N);        e=0;        //节点的状态,-1表示没有被访问过        memset(st,-1,sizeof(st));        int fa;        //输入节点的父节点信息,并存储        for(int i=2;i<=N;i++)        {            scanf("%d",&fa);            add(fa,i);        }        //初始化以下几个结构体,节点度数的左右范围/        for(int i=1;i<=N;i++)        {            L[i].clear();            R[i].clear();            del[i].clear();        }        int Q,u,l,r,d;        //输入操作的个数        scanf("%d",&Q);        while(Q--)        {            scanf("%d%d%d%d",&u,&l,&r,&d);            //将用户输入的深度范围存储起来            L[u].push_back(l);            R[u].push_back(r);            del[u].push_back(d);        }        memset(tr,0,sizeof(tr));        //核心算法,dfs-深度优先搜索遍历        dfs(1,1);        printf("Case %d: %lld\n",++cas,cal());    }}/*10121 1 2 2 2 2 3 3 3 10 11*/

3 . 活动中心(类似于之前的一个集会的问题,用的三分法):

/* * main.cpp * *  Created on: 2014-4-19 *      Author: zy */#include<iostream>#include<iostream>#include<string>#include<cstring>#include<vector>#include<cmath>   //pow函数所需要的头文件#include<iomanip> //setprecision控制小数点的个数using namespace std;long long x[500000],y[500000];const double eps = 1e-6;  //精度int N;double cal(double m){double ans = 0;for(int i =0; i< N; i++) {double len=sqrt((x[i]-m)*(x[i]-m)+y[i]*y[i]);ans = ans + len;}return ans;}int main(){int T;cin >> T;double result;  //输出结果int count = 1;while(T--) {//输入数据,做相应替换cin >> N;for(int i=0; i<N; i++) {cin >> x[i] >> y[i];}//核心算法double left = -1000000;double right = 1000000;//三分查找算法while(1) {double mid = (left+right)/2;double midMid = (mid+right)/2;double retMid = cal(mid);double retMidMid = cal(midMid);if(retMid < retMidMid) right = midMid;else left = mid;if(right - left < eps) {result = right;break;}}//输出结果,控制double型的小数点位数cout<<"Case "<< count<<": ";cout << fixed << setprecision(6) << result<<endl;count++;}result = 0;}


0 1
原创粉丝点击