组队周赛_山东省第一届ACM大学生程序设计竞赛

A.Phone Number

一水,赛后听Triple_Sb是用字典树做的,逗逼了。。。
就简单的strncmp()函数的应用。。。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>

using namespace std;
char str[1010][100];
int main()
{
    int t,i,j,n;
    while(~scanf("%d",&n)&&n)
    {
        int f=0;
        for(i=0;i<n;i++)
            scanf("%s",str[i]);
        for(i=0;i<n;i++)
        {
            int li=strlen(str[i]);
            for(j=0;j<n;j++)
            {
                if(i==j)continue;
                int lj=strlen(str[j]);
                int l=min(li,lj);
                if(strncmp(str[i],str[j],l)==0)
                {
                    f=1;
                    break;
                }
            }
        }
        if(f)printf("NO\n");
        else printf("YES\n");
    }
    return 0;
}

C.Hello World!

赛中这题不是我做的,Hypo+wz做了,先贴他们的代码,回头补补。。。
回头写写,WA了。。。下了数据测试下,没有错误。。。
最后在Ball的测试数据下才发现自己的排序出问题了。。。
逗了,用了很久的sort瞬间都不会了。。。
#include <iostream>   
#include <stdio.h>   
#include <algorithm>   
#include <stdio.h>   
  
using namespace std;   
struct node   
{   
    int x,y,t;   
  
} num[10010],pp[10010];   

int cmp(node  a,node  b)
{
    if(a.x!=b.x)
		return a.x<b.x;
	else
		return a.y<b.y;
}

int cmp1(node  a,node  b)
{
    return a.t<b.t;
}

int main()   
{   
    int t,i,j,n,k=1,f;  
    while(~scanf("%d",&n)&&n)   
    {   
        for(i=0; i<n; i++)   
        {   
            scanf("%d%d",&num[i].x,&num[i].y);   
            num[i].t=i;   
        }   
        sort(num,num+n,cmp); 
        printf("Case %d:\n",k++);   
        int cnt=0;   
        for(i=0; i<n; i++)   
        {   
            f=0;   
            for(j=i+1; j<n; j++)   
            {   
                if(num[j].x>num[i].x&&num[j].y>num[i].y)   
                {   
                    pp[cnt].x=num[j].x;   
                    pp[cnt].y=num[j].y;   
                    pp[cnt++].t=num[i].t;   
                    f=1;   
                    break;   
                }   
            }   
            if(f==0)   
            {   
                pp[cnt].x=-1;   
                pp[cnt].t=num[i].t;   
                pp[cnt++].y=-1;   
            }   
        }   
        sort(pp,pp+cnt,cmp1);   
        for(i=0;i<cnt;i++)   
            printf("%d %d\n",pp[i].x,pp[i].y);   
            printf("\n");   
    }   
    return 0;   
}   

D.Greatest Number

比赛这题我一看,很像背包的题目,要是背包就不会了,交给队友wz去想,比赛结束也没能A了,赛后找了题解,原来可以暴力出来,普通暴力是不行的,任意小于四个数相加,数据范围1000,也就是开1000*1000*1000*1000,没办法存下来,但是可以存下任意两个数的和,然后巧妙地在暴力二分出小于m的最大数。。。
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <string.h>

using namespace std;
int num[10100000];

int main()
{
    int n,m,i,j,t,k,kk=1;
    //freopen("greatest.in","r",stdin);

    while(~scanf("%d%d",&n,&m)&&n+m)
    {
        memset(num,0,sizeof(num));
        j=1;
        num[0]=0;//0个数相加
        for(i=1; i<=n; i++)
        {
            scanf("%d",&t);
            if(t>m)continue;
            num[j++]=t;//1个数相加
        }
        k=j;
        n=j;
        for(i=1; i<n; i++)
        {
            for(j=i; j<n; j++)
            {
                if(num[i]+num[j]<=m)
                {
                    num[k++]=num[i]+num[j];//两个数相加
                }
            }
        }
        n=k;
        sort(num,num+n);
        int r=n-1,u=n-1,l,maxx=0,f=0;
        for(i=0; i<n; i++)
        {
            l=i;//每次选一个数进行二分查找小于m的数
            f=0;
            while(l<=r)
            {
                int mid=(l+r)/2;
                int key=num[i]+num[mid];
                if(key==m)//如果存在m
                {
                    maxx=m;
                    f=1;
                    break;
                }
                else if(key>m)//如果大于m,缩小范围查找
                {
                    r=mid-1;
                }
                else//如果小于m
                {
                    l=mid+1;
                    if(maxx<key)
                    {
                        maxx=key;
                        //u=mid;
                    }
                }
            }
                if(f)break;
            //r=u;
            r=n-1;
        }

        printf("Case %d: %d\n\n",kk++,maxx);
    }
    return 0;
}


F.Emergency

这题就是求有向单源最短路,题目不是我读的,wz读完题跟我说是最小生成树,一听,我就自己单干,先敲个最小生成树的模板,然后一看就不对,明明是最短路问题,赶紧写DIJKstra算法,由于只能走标记的点,wz跟我说了一个技巧,听好使的,结果超时了,一想不对,又没考虑时间复杂度的问题。。。
在一旁想了一会,才发现这题曾经做过。。。冏。。。
换了flody算法。。。结果WA,手残了,少了Case和回车。。。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#define inf 10000000

using namespace std;
int n,m;
int mmap[1060][1060];
int va[1060];
void flody(int k)
{
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
        if(mmap[i][j]>mmap[i][k]+mmap[k][j])
            mmap[i][j]=mmap[i][k]+mmap[k][j];
}
int main()
{
    int q,i,j,a,b,c,p,lp,s,e,k=1;
    while(~scanf("%d%d%d",&n,&m,&q))
    {
        memset(va,0,sizeof(va));
        if(!n&&!m&&!q)break;
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
                mmap[i][j]=inf;
            mmap[i][i]=0;
        }
        for(i=0;i<m;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            if(c<mmap[a][b])
                mmap[a][b]=c;
        }
        printf("Case %d:\n",k++);
        while(q--)
        {
            scanf("%d",&p);
            if(p==0)
            {
                scanf("%d",&lp);
                if(va[lp])
                    printf("City %d is already recaptured.\n",lp);
                else
                    flody(lp);
                va[lp]=1;

            }
            else if(p==1)
            {
                scanf("%d%d",&s,&e);
                if(!va[s]||!va[e])
                    printf("City %d or %d is not available.\n",s,e);
                else
                {
                        int d=mmap[s][e];
                    if(d==inf)
                    printf("No such path.\n");
                    else
                    printf("%d\n",d);
                }
            }
        }
        printf("\n");
    }
    return 0;
}

G.Shopping

一看又是签到题。。。好像还可以直接(最大-最小)/2
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>

using namespace std;
int num[1000100];
int main()
{
    int t,i,j,n;
    while(~scanf("%d",&n)&&n)
    {
        memset(num,0,sizeof(num));
        int sum=0;
        for(i=0;i<n;i++)
            scanf("%d",&num[i]);
        sort(num,num+n);
        for(i=1;i<n;i++)
        {
            sum+=num[i]-num[i-1];
        }
        sum+=abs(num[n-1]-num[0]);
        printf("%d\n",sum);
    }
    return 0;
}

I.Balloons

没读题,就看到测试数据,一个裸DFS。。。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>

using namespace std;
char mmap[200][200];
int dx4[]={-1,0,1,0};
int dy4[]={0,1,0,-1};
int dx8[]={-1,0,1,-1,1,-1,0,1};
int dy8[]={-1,-1,-1,0,0,1,1,1};
int vis4[200][200];
int vis8[200][200];
int n;
void s_dfs(int s,int e)
{
    for(int i=0;i<4;i++)
    {
        int x=s+dx4[i];
        int y=e+dy4[i];
        if(x>=0&&x<n&&y>=0&&y<n&&!vis4[x][y]&&mmap[x][y]!='0')
        {
            vis4[x][y]=1;
            s_dfs(x,y);
        }
    }
}
void k_dfs(int s,int e)
{
    for(int i=0;i<8;i++)
    {
        int x=s+dx8[i];
        int y=e+dy8[i];
        if(x>=0&&x<n&&y>=0&&y<n&&!vis8[x][y]&&mmap[x][y]!='0')
        {
            vis8[x][y]=1;
            k_dfs(x,y);
        }
    }
}
int main()
{
    int i,j,k=1;
    while(~scanf("%d",&n)&&n)
    {
        int cnt4=0;
        int cnt8=0;
        memset(vis4,0,sizeof(vis4));
        memset(vis8,0,sizeof(vis8));
        memset(mmap,0,sizeof(mmap));
        for(i=0;i<n;i++)
            scanf("%s",mmap[i]);
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
                if(mmap[i][j]=='1'&&!vis4[i][j])
                {
                    vis4[i][j]=1;
                    s_dfs(i,j);
                    cnt4++;
                }
        }
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
                if(mmap[i][j]=='1'&&!vis8[i][j])
                {
                    vis8[i][j]=1;
                    k_dfs(i,j);
                    cnt8++;
                }
        }
        printf("Case %d: %d %d\n",k++,cnt4,cnt8);
        printf("\n");
    }
    return 0;
}

赛后总结
组队赛还是不够好,在我看来理想的组队时先队友A自己的题,保证自己的出题速度和效率,一道题至少要有两个人读题。。。而且不应该在比赛前期的时候,两个人做一题,这样出题没效率。。。还有就是坚持到最后,这一次我们队确实输在这一点上,还有一个小时的时候,就放弃了,有两题都卡TLE了,就没人去解。。。而Triple_Sb的soring一直到最后半小时的时候给A了一题,反超我们队。。。
自己在做题读题方便还是不行,手残了好几次,贡献了罚时。。。不能一直读完一题。。。其实还是英语的问题。。。基本不怎么和队友合作。。。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值