NEFU要崛起——第5场

来源:互联网 发布:unity3d像素鸟教程 编辑:程序博客网 时间:2024/05/15 07:43

比赛地址:http://acm.hust.edu.cn:8080/judge/contest/view.action?cid=17898#overview

第1题;判断四个长度不一的边能否构成三角形。。。

分析:纯粹判断题,排序后更简单。。。

#include<cstdio>#include<iostream>#include<algorithm>using namespace std;int a[4],c;int solve(){    if(a[0]+a[1]>a[2])return 1;    if(a[1]+a[2]>a[3])return 1;    if(a[0]+a[1]==a[2])return 2;    if(a[1]+a[2]==a[3])return 2;    return 0;}int main(){    while(~scanf("%d%d%d%d",&a[0],&a[1],&a[2],&a[3]))    {        sort(a,a+4);        c=solve();        if(c==0)puts("IMPOSSIBLE");        if(c==1)puts("TRIANGLE");        if(c==2)puts("SEGMENT");    }    return 0;}

第2题:给你一张n*m的地图,地图上有一些大写字母,每一个字母代表一个人,问与给定字母相邻的人有几个?

分析:直接枚举相邻的两个字母,判断其中是否有给定的字母,有的话就标记两个人。。。注意边界,我偷懒导致wa了

代码:

#include<cstdio>#include<cstring>#include<iostream>using namespace std;const int mm=111;char map[mm][mm],ps;int p[333];int i,j,n,m,ans;int main(){    while(~scanf("%d%d %c",&n,&m,&ps))    {        for(i=0;i<n;++i)            scanf("%s",map[i]);        memset(p,0,sizeof(p));        p[ps]=1;        for(i=0;i<n;++i)            for(j=0;j<m;++j)            {                if(map[i][j]==ps)                {                    if(j)p[map[i][j-1]]=1;                    if(i)p[map[i-1][j]]=1;                }                if(i&&map[i-1][j]==ps)p[map[i][j]]=1;                if(j&&map[i][j-1]==ps)p[map[i][j]]=1;            }        ans=-1;        for(i='A';i<='Z';++i)ans+=p[i];        printf("%d\n",ans);    }    return 0;}

第3题:给你n块巧克力,吃完每块需要的时间,问两个人从两边开始吃,最后他们都吃了几块,同时吃的情况,让给左边的女生

分析:直接开两个指针,还有统计两个人所花的时间,直接模拟即可。。。

代码:

#include<cstdio>#include<iostream>#include<cstring>using namespace std;const int mm=111111;int t[mm];int i,j,n,ta,tb;int main(){    while(~scanf("%d",&n))    {        for(i=1;i<=n;++i)            scanf("%d",&t[i]);        ta=tb=0;        i=1,j=n;        while(i<=j)        {            if(ta<=tb)ta+=t[i++];            else tb+=t[j--];        }        printf("%d %d\n",i-1,n-i+1);    }    return 0;}

第4题:给你n个人,每次你可以打中2~n-1中的任何一个,与他相邻的也会受到b的伤害,死后也可以继续打,太凶残了= =

分析:数据较小,所以我立马想到可以用搜索搞,考虑按顺序来搞,第一个人只能通过第二个位置来搞定,所以第二个位置至少要放置的火球数已知,考虑普通情况下,前一个人还没死,那么至少需要的火球数也可以计算,所以可以枚举每一个位置的火球数来模拟计算,加个最优化剪枝直接搞定。。。当然也有DP的解法。。。

代码:

#include<cstdio>#include<cstring>#include<iostream>using namespace std;int h[22],t[22],s[22],out[22];int i,a,b,n,ans;int count(int s,int a){    int ret=0;    while(s>=0)s-=a,++ret;    return ret;}void dfs(int l,int sum){    if(sum>=ans)return;    int i,tmp;    if(l==n)    {        tmp=max(count(h[n]-s[n],b),count(h[n-1]-s[n-1],a));        if(ans>sum+tmp)        {            ans=sum+tmp;            for(i=2;i<n;++i)out[i]=t[i];            out[n-1]+=tmp;        }        return;    }    tmp=count(h[l-1]-s[l-1],b);    if(tmp+sum>=ans)return;    s[l-1]+=b*(tmp-1),s[l]+=a*(tmp-1),s[l+1]+=b*(tmp-1);    for(i=tmp;i<44;++i)    {        s[l-1]+=b,s[l]+=a,s[l+1]+=b,t[l]=i;        dfs(l+1,sum+i);    }    s[l-1]-=b*(i-1),s[l]-=a*(i-1),s[l+1]-=b*(i-1);}int main(){    while(~scanf("%d%d%d",&n,&a,&b))    {        for(i=1;i<=n;++i)            scanf("%d",&h[i]);        ans=2e9;        memset(s,0,sizeof(s));        memset(t,0,sizeof(t));        dfs(2,0);        printf("%d\n",ans);        for(i=2;i<n;++i)            while(out[i]--)printf("%d ",i);        puts("");    }    return 0;}

第5题:给你n本书,问最长的区间,使得区间内最高的书与最矮的书的高度差不超过n的最大长度,还有这样长度的区间有哪几个。。。

分析:看到n的范围,应该都知道至少要O(nlogn)的算法,普通的方法就是枚举区间两个端点,[i,j]然后判断这个区间是否满足条件,这样明显超时了,由于题目的特殊行,如果[i,j]满足条件,那么[i+1,j]必然满足条件,这个有什么用呢?我们每次整加i的时候,不用重新枚举j的范围了,呵呵,但是问题又来了,刚才那种方法可以在枚举j的时候找到最值,现在怎么办?当然得用线段树之类的区间最值求法了。。。

所以方案就是枚举加线段树,哈哈

代码:

#include<cstdio>#include<iostream>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;const int mm=111111;int ma[mm<<2],mi[mm<<2],ql[mm],qr[mm];int i,j,k,n,ans,t;void build(int l,int r,int rt){    if(l==r)    {        scanf("%d",&ma[rt]);        mi[rt]=ma[rt];        return ;    }    int m=(l+r)>>1;    build(lson);    build(rson);    ma[rt]=max(ma[rt<<1],ma[rt<<1|1]);    mi[rt]=min(mi[rt<<1],mi[rt<<1|1]);}int queryma(int L,int R,int l,int r,int rt){    if(L<=l&&R>=r)return ma[rt];    int m=(l+r)>>1,ret=0;    if(L<=m)ret=max(ret,queryma(L,R,lson));    if(R>m)ret=max(ret,queryma(L,R,rson));    return ret;}int querymi(int L,int R,int l,int r,int rt){    if(L<=l&&R>=r)return mi[rt];    int m=(l+r)>>1,ret=2e9;    if(L<=m)ret=min(ret,querymi(L,R,lson));    if(R>m)ret=min(ret,querymi(L,R,rson));    return ret;}int main(){    while(~scanf("%d%d",&n,&k))    {        build(1,n,1);        ans=t=0;        for(i=j=1;j<=n;++i)        {            if(j<i)j=i;            while(j<=n&&(queryma(i,j,1,n,1)-querymi(i,j,1,n,1)<=k))++j;            if(j-i>ans)ans=j-i,ql[0]=i,qr[0]=j-1,t=1;            else if(j-i==ans)ql[t]=i,qr[t++]=j-1;        }        printf("%d %d\n",ans,t);        for(i=0;i<t;++i)printf("%d %d\n",ql[i],qr[i]);    }    return 0;}



原创粉丝点击