2013年3月24日周赛结题报告

赛间出了5道,赛后通过各种途径又弄了2道,感觉干不动了,还有3道真心不想干了。

第一题,是个大水题,算出总长,在算出两点之间的正着走的长度,在总长捡它,输出小的即可。

第二题,就是给你好多个字符串,任务是找出最小的不是它们子串的字符串,你的字符串大小判断是这样的a,b,c........z,aa,ab,ac.......az,ba,bb,bc.......bz,ca,......zz,aaa,........,反正我差不多就当数字做了,模拟进位,用string里的find判断子串,然后就ok了

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n,num;
string s[40],a;
bool solve()
{
    for(int i=0;i<n;i++)
    {
        if(s[i].find(a)!=-1)return false;
    }
    return true;
}
void add(int m,int jin)
{
    if(jin==0)return;
    if(m>0)
    {
        if(a[m-1]!='z')
        {
            a[m-1]+=1;
            return;
        }
        else
        {
            a[m-1]='a';
            add(m-1,1);
        }
    }
    else
    {
        a="a"+a;
        num++;
    }
}
void go()
{
    while(1)
    {
        if(solve())
        {
            cout<<a<<endl;
            return ;
        }
        add(num,1);
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++)cin>>s[i];
    a="a";
    num=1;
    go();
    return 0;
}

第三题,就是个并查集的题,不难,设一个f数组记录父子关系,r数组记录语言对应的人,下面拿第一组数据为例说明下

5 5
1 2
2 2 3
2 3 4
2 4 5
1 5
第一行是代表5个人,5语言

第一个人会2语言,由于2在之前数据没人会(这里这是第一个数据),让r[2]=1;

第二个人会2,3语言,应为2语言第一个人会(r[2]=1)所以合并1,2俩人,f[2]=1了,3语言之前没人会,让r[3]=2;

。。。。。。(之后就这样依次类推)

最后只要看n个人分成了几摞就可以了,就是n个人f[x]=x的个数;

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int m,n,num,yu,ans,sum;
int f[105],r[105];
int find(int i)
{
    if(f[i]==i)return i;
    else return find(f[i]);
}
void un(int a,int b)
{
    int x=find(a);
    int y=find(b);
    f[x]=y;
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        sum=0;
        for(int i=1;i<=n;i++)f[i]=i;
        memset(r,0,sizeof(r));
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&num);
            if(num)sum=1;
            for(int j=0;j<num;j++)
            {
                scanf("%d",&yu);
                if(r[yu]==0)r[yu]=i;
                else un(i,r[yu]);
            }
        }
        if(sum==0)
        {
            cout<<n<<endl;
            continue;
        }
        ans=0;
        for(int i=1;i<=n;i++)
        {
            if(f[i]==i)ans++;
        }
        cout<<ans-1<<endl;
    }
    return 0;
}

第四题,自由发挥度很大啊,乱搞之。

题目意思是要n个点,这n点只能构成最多m边凸边形,输出符合的n个点就可以,只要符合就可以,无固定答案。

一开始是搞圆,外圆上均匀去m点,内圆上均匀取剩下的点,开始时3点共线,改写了下,不共线了但答案错误。

借鉴了网上的方法,用的x正半轴方向二次函数,y=x^2上面取m点,y=-x^2去剩下的点,在让上面下面的点距离拉大,上面的+一个大数,下面-大数。神了

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main()
{
    int m,n,a,b;
    scanf("%d%d",&n,&m);
    if(m==3&&n>4)
    {
        cout<<-1<<endl;
    }
    else
    {
        for(int i=1;i<=m;i++)
        {
            cout<<i<<" "<<1000000+i*i<<endl;
        }
        n-=m;
        for(int i=1;i<=n;i++)
        {
            cout<<i<<" "<<-1000000-i*i<<endl;
        }
    }
    return 0;
}

第五题,。。。。

第六题,水题,只要处理奇数次的就可以了,偶数次对结果不影响。

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int main()
{
    int a[5][5];
    int b[5][5];
    for(int i=1;i<=3;i++)
    {
        for(int j=1;j<=3;j++)
        {
            scanf("%d",&a[i][j]);
            b[i][j]=1;
        }
    }
    for(int i=1;i<=3;i++)
    {
        for(int j=1;j<=3;j++)
        {
            if(a[i][j]%2==1)
            {
                b[i][j]=-b[i][j];
                b[i-1][j]=-b[i-1][j];
                b[i+1][j]=-b[i+1][j];
                b[i][j-1]=-b[i][j-1];
                b[i][j+1]=-b[i][j+1];
            }
        }
    }
    for(int i=1;i<=3;i++)
    {
        for(int j=1;j<=3;j++)
        {
            if(b[i][j]==1)cout<<1;
            else cout<<0;
        }
        cout<<endl;
    }
    return 0;
}

第七题,有m*n的格子,有黑有白,要判断是否任意两黑格间能到达对方,只经过其他黑格并且转弯次数只能最多1次。这题由于数据不是很大,枚举任意俩黑格,全部验证一遍即可。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int m,n;
char a[55][55];
bool hen(int x1,int y1,int x2,int y2)
{
    if(x1>x2)
    {
        for(int i=x1; i>=x2; i--)
        {
            if(a[i][y1]!='B')return false;
        }
        for(int i=y1; i<=y2; i++)
        {
            if(a[x2][i]!='B')return false;
        }

    }
    else
    {
        for(int i=x1; i<=x2; i++)
        {
            if(a[i][y1]!='B')return false;
        }
        for(int i=y1; i<=y2; i++)
        {
            if(a[x2][i]!='B')return false;
        }

    }
     return true;
}
bool shu(int x1,int y1,int x2,int y2)
{
    for(int i=y1; i<=y2; i++)
    {
        if(a[x1][i]!='B')return false;
    }
    if(x1>x2)
    {
        for(int i=x1; i>=x2; i--)
        {
            if(a[i][y2]!='B')return false;
        }
    }
    else
    {
        for(int i=x1; i<=x2; i++)
        {
            if(a[i][y2]!='B')return false;
        }
    }
    return true;
}
bool  go()
{
    for(int i=0; i<m; i++)
    {
        for(int j=0; j<n; j++)
        {
            if(a[i][j]=='B')
            {
                for(int x=i; x<m; x++)
                {
                    for(int y=0; y<n; y++)
                    {
                        if(a[x][y]=='B')
                        {
                            if(hen(i,j,x,y)||shu(i,j,x,y))continue;
                            else return false;
                        }
                    }
                }
            }
        }
    }
    return true;
}
int main()
{
    while(scanf("%d%d",&m,&n)!=EOF)
    {
        //getchar();
        for(int i=0; i<m; i++)
        {
            scanf("%s",&a[i]);
            //scanf("%c",&a[i][j]);
            //getchar();
        }
        if(go())cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
    return 0;
}

第八题,开始时想麻烦了,其实不难。

意思是,给你n个数和k,要你从中取数,去了x就不能取x*k,问做多能取几个。思路先排序,然后从头到尾遍历,第一个肯定取,将第一个数k倍的标记代表不能取它了,然后以后的数先判断是否被标记了,被标记则跳过,没被标记则取,并标记它的k倍,就ok了。

#include<iostream>
#include<cstdio>
#include<map>
#include<algorithm>
long long int a[100005];
using namespace std;
int main()
{
    int n,k,ans;
    while(scanf("%d%d",&n,&k)!=EOF){
        map<long long int,int >p;
        ans=0;
    for(int i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
    }
    sort(a,a+n);
    for(int i=0;i<n;i++)
    {
        if(p[a[i]]==0)
        {
            ans++;
            p[k*a[i]]=1;
        }
    }
    cout<<ans<<endl;}
    return 0;
}

第九题,。。。

第十题,。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值