复旦2012ACM校赛

来源:互联网 发布:ping ip软件 编辑:程序博客网 时间:2024/05/09 07:25

挺久之前做的题了,具体过程忘掉了,最近终于看懂了划分树,补了一道模版题。
A:
HDU 4245
一开始理解错了题意,以为只能是单向映射,没想到是双向的,在原代码基础上修改导致代码打的很渣。

#include<iostream>#include<string>#include<algorithm>#include<map>using namespace std;map<string,string> a;void pre(){    a["Ab minor"]="G# minor";    a["G# minor"]="Ab minor";    a["A# major"]="Bb major";    a["Bb major"]="A# major";    a["A# minor"]="Bb minor";    a["Bb minor"]="A# minor";    a["C# major"]="Db major";    a["Db major"]="C# major";    a["Db minor"]="C# minor";    a["C# minor"]="Db minor";    a["D# major"]="Eb major";    a["Eb major"]="D# major";    a["D# minor"]="Eb minor";    a["Eb minor"]="D# minor";    a["Gb major"]="F# major";    a["F# major"]="Gb major";    a["Gb minor"]="F# minor";    a["F# minor"]="Gb minor";    a["G# major"]="Ab major";    a["Ab major"]="G# major";    return;}int main(){    ios::sync_with_stdio(false);    pre();    string s;    int t=0;    while(getline(cin,s)){        cout<<"Case "<<++t<<": ";        if(a.count(s)) cout<<a[s]<<endl;        else cout<<"UNIQUE"<<endl;    }    return 0;}

C:
HDU 4247

读题之后感觉是这么做,就交了,然后就过了。#include<iostream>#include<algorithm>using namespace std;int main(){    ios::sync_with_stdio(false);    long long a[4],t=0;    while(cin>>a[0]>>a[1]>>a[2]>>a[3]){        sort(a,a+4);        cout<<"Case "<<++t<<": ";        cout<<a[2]+a[3]<<endl;    }    return 0;}

G:
求区间的中位数,用划分树就能过。
为了补这道题,去学了划分树和线段树。

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAXN=100010;int tree[20][MAXN];//表示每层每个位置的值int sorted[MAXN];//已经排序好的数int toleft[20][MAXN];//toleft[p][i]表示第i层从1到i有数分入左边void build(int l,int r,int dep){    if(l==r)return;    int mid=(l+r)>>1;    int same=mid-l+1;//表示等于中间值而且被分入左边的个数    for(int i=l;i<=r;i++)//注意是l,不是one        if(tree[dep][i]<sorted[mid]) same--;    int lpos=l;    int rpos=mid+1;    for(int i=l;i<=r;i++){        if(tree[dep][i]<sorted[mid]) tree[dep+1][lpos++]=tree[dep][i];        else if(tree[dep][i]==sorted[mid]&&same>0){            tree[dep+1][lpos++]=tree[dep][i];            same--;        }        else tree[dep+1][rpos++]=tree[dep][i];        toleft[dep][i]=toleft[dep][l-1]+lpos-l;    }    build(l,mid,dep+1);    build(mid+1,r,dep+1);}//查询区间第k大的数,[L,R]是大区间,[l,r]是要查询的小区间int query(int L,int R,int l,int r,int dep,int k){    if(l==r)return tree[dep][l];    int mid=(L+R)>>1;    int cnt=toleft[dep][r]-toleft[dep][l-1];    if(cnt>=k){        int newl=L+toleft[dep][l-1]-toleft[dep][L-1];int newr=newl+cnt-1;        return query(L,mid,newl,newr,dep+1,k);    }    else{        int newr=r+toleft[dep][R]-toleft[dep][r],newl=newr-(r-l-cnt);        return query(mid+1,R,newl,newr,dep+1,k-cnt);    }}int main(){    int n,m,t=0;    while(~scanf("%d",&n)){        memset(tree,0,sizeof(tree));        for(int i=1;i<=n;i++){            scanf("%d",&tree[0][i]);            sorted[i]=tree[0][i];        }        sort(sorted+1,sorted+n+1);        build(1,n,0);        scanf("%d",&m);        printf("Case %d:\n",++t);        int s,t,k;        while(m--){            scanf("%d%d",&s,&t);            k=(t-s+2)/2;            printf("%d\n",query(1,n,s,t,0,k));        }    }    return 0;}

H:
HDU 4252
给出每个点的高度,求最少有几个建筑。具体记不清了,只记得当时出的很快。

#include<cstdio>#include<algorithm>#include<set>using namespace std;set<int> a;int main(){    int n,t=0;    while(~scanf("%d",&n)){        a.clear();        int cnt=0;        for(int i=0;i<n;++i){            int cur;            scanf("%d",&cur);            if(!cur) ++cnt,a.clear();            else{                if(a.count(cur)) ++cnt;                set<int>::iterator it1=a.lower_bound(cur),it2=a.end();                a.erase(it1,it2);                a.insert(cur);            }        }        printf("Case %d: %d\n",++t,n-cnt);    }    return 0;}

J:
HDU 4254
比赛时没推出来公式,赛后听说是这个公式,原理还不知道。。

#include<cstdio>int main(){    int t=0;    double p,q;    while(~scanf("%lf%lf%lf",&p,&p,&q))        printf("Case %d: %.4lf\n",++t,(q+1)/(p+2));    return 0;}

K:
HDU 4255
蛇形填数,之后BFS,坑在于,有可能素数连起来一直到了边界,导致判断出错,一开始数组开小了,WA了一次,不知道为什么不是RE,后来改大数组,大力出奇迹就过了。

#include<cstdio>#include<cstring>#include<queue>#include<iostream>using namespace std;const int maxn=210;const int go[4][2]={{1,0},{-1,0},{0,1},{0,-1}};int g[maxn][maxn],vis[maxn][maxn];bool np[maxn*maxn]={1,1};struct point{    int x,y;    point(int x=0,int y=0):x(x),y(y){}}a[maxn*maxn+1];queue<point> q;void pre(){    int k=maxn*maxn;    for(int i=2;i<k;++i)        if(!np[i]) for(int j=i*i;j<k;j+=i) np[j]=true;    int tot=k;    int x,y;    g[x=0][y=maxn-1]=k;a[tot]=point(x,y);    while(tot>0){        while(x+1<maxn&&!g[x+1][y]){            --tot;++x;            if(!np[tot]) continue;            g[x][y]=tot;a[tot]=point(x,y);        }        while(y-1>=0&&!g[x][y-1]){            --tot;--y;            if(!np[tot]) continue;            g[x][y]=tot;a[tot]=point(x,y);        }        while(x-1>=0&&!g[x-1][y]){            --tot;--x;            if(!np[tot]) continue;            g[x][y]=tot;a[tot]=point(x,y);        }        while(y+1<maxn&&!g[x][y+1]){            --tot;++y;            if(!np[tot]) continue;            g[x][y]=tot;a[tot]=point(x,y);        }    }    return;}int main(){    pre();    int st,ed,t=0;    while(~scanf("%d%d",&st,&ed)){        memset(vis,-1,sizeof(vis));        while(!q.empty()) q.pop();        q.push(a[st]);        vis[a[st].x][a[st].y]=0;        while(!q.empty()){            if(vis[a[ed].x][a[ed].y]!=-1) break;            point cur=q.front();q.pop();            for(int i=0;i<4;++i){                int x=cur.x+go[i][0],y=cur.y+go[i][1];                if(vis[x][y]!=-1||!g[x][y]) continue;                q.push(a[g[x][y]]);                vis[x][y]=vis[cur.x][cur.y]+1;            }        }        printf("Case %d: ",++t);        if(vis[a[ed].x][a[ed].y]!=-1) printf("%d\n",vis[a[ed].x][a[ed].y]);        else printf("impossible\n");    }    return 0;}

L:
HDU 4256
水题,打表过。

#include<iostream>#include<string>#include<map>using namespace std;map<string,int> a;void pre(){    a["I"]=1;    a["II"]=2;    a["III"]=3;    a["IV"]=4;    a["V"]=5;    a["VI"]=6;    a["VII"]=7;    a["VIII"]=8;    a["IX"]=9;    a["X"]=10;    a["XI"]=11;    a["XII"]=12;    return;}int main(){    ios::sync_with_stdio(false);    pre();    string s;    int t=0;    while(cin>>s){        cout<<"Case "<<++t<<": "<<a[s]<<endl;    }    return 0;}
0 0
原创粉丝点击