Helvetic Coding Contest 2018 online mirror (teams allowed, unrated) easy难度

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_37428263/article/details/79979329

点击打开链接

A1:思维题

#include <bits/stdc++.h>
using namespace std;
char s[15][15],s1[15][15];
int main()
{
    int n,cnt1=0;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
     {
         scanf("%s",&s[i]);
         for(int j=0;j<n;j++)
            if(s[i][j]=='O') cnt1++;
     }
    for(int i=0;i<n;i++)
    {
        scanf("%s",&s1[i]);
        for(int j=0;j<n;j++)
            if(s1[i][j]=='O') cnt1--;
    }
    bool flag;
    if(cnt1) flag=false;
    else {
        bool flag1=true,flag2=true,flag3=true,flag4=true,flag5=true,flag6=true,flag7=true,flag8=true;
        //从四个点开始读取
        char k[15][15];
        //0 0
        //向右读取
        memcpy(k,s1,sizeof(s1));
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                if(k[i][j]!=s[i][j]) {
                  flag1=false;
                  break;
               }
        //向下读取
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                 k[i][j]=s1[j][i];
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                if(k[i][j]!=s[i][j]) {
                  flag2=false;
                  break;
               }
        //0 n-1
        //向左读取
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                k[i][j]=s1[i][n-1-j];
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                if(k[i][j]!=s[i][j]) {
                  flag3=false;
                  break;
               }
        //向下
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                 k[i][j]=s1[j][n-1-i];
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                if(k[i][j]!=s[i][j]) {
                  flag4=false;
                  break;
               }
        //n-1 0
        //向上
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                k[i][j]=s1[n-1-j][i];
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                if(k[i][j]!=s[i][j]) {
                  flag5=false;
                  break;
               }
        //向右
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                k[i][j]=s1[n-1-i][j];
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                if(k[i][j]!=s[i][j]) {
                  flag6=false;
                  break;
               }
        //n-1 n-1
        //向左
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                k[i][j]=s1[n-1-i][n-1-j];
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                if(k[i][j]!=s[i][j]) {
                  flag7=false;
                  break;
               }
        //向上
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                k[i][j]=s1[n-1-j][n-1-i];
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                if(k[i][j]!=s[i][j]) {
                  flag8=false;
                  break;
               }
        if(flag1||flag2||flag3||flag4||flag5||flag6||flag7||flag8) flag=true;
        else flag=false;
    }
    if(flag) printf("Yes\n");
    else printf("No\n");
    return 0;
}

B1:水题(求树中叶子节点的个数)

#include<bits/stdc++.h>
using namespace std;
const int maxn=1000+5;
vector<int>G[maxn];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        G[i].clear();
    for(int i=0;i<n-1;i++)
    {
        int v1,v2;
        scanf("%d%d",&v1,&v2);
        G[v1].push_back(v2);
        G[v2].push_back(v1);
    }
    int cnt=0;
    for(int i=1;i<=n;i++)
        if(G[i].size()==1) cnt++;
    printf("%d\n",cnt);
    return 0;
}

C1:打表+暴力枚举

//打表 枚举切割点
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int main()
{
    int a[maxn];
    int n,p;
    scanf("%d%d",&n,&p);
    for(int i=0;i<n;i++)
    {
         int k;
         scanf("%d",&k);
         a[i]=k%p;
    }
    int sum1[maxn],sum2[maxn];
    int m=-1;
    sum1[0]=a[0];
    sum2[0]=a[n-1];
    //前缀和
    for(int i=1;i<n;i++)
        sum1[i]=sum1[i-1]+a[i];
    //后缀和
    for(int i=1;i<n;i++)
        sum2[i]=sum2[i-1]+a[n-i-1];
    //枚举
    for(int i=0;i<=n-2;i++)
    {
        m=max(m,(sum1[i]%p+sum2[n-2-i]%p));
    }
    printf("%d\n",m);
    return 0;
}

D1:STL 注意开double

#include<bits/stdc++.h>
using namespace std;
const int maxn=2*1e5+5;
int main()
{
    int n;
    scanf("%d\n",&n);
    map<double,int>str;
    double p[maxn];
    str.clear();
    for(int i=0;i<n;i++)
    {
        int a,b,c;
        scanf("(%d+%d)/%d\n",&a,&b,&c);
        p[i]=(double)(a+b)/c;
        str[p[i]]++;
    }
    for(int i=0;i<n;i++)
        printf("%d ",str[p[i]]);
    return 0;
}

E1:计算几何 (判断两条线段是否存在交点)(使用快速排斥粗略判断,使用跨立实验精确判断)

//判断两线段是否相交:快速排斥初步判断+跨立实验精确判断
#include<bits/stdc++.h>
using namespace std;
const double eps=0.00000001;
struct point{
double x,y;
};
struct line{
point m,n;
};
point p[15],q[15];
line k[15];
bool solve(point a,point b,point c,point d)                        //有交点返回true
{
        //快速排斥:判断以两条直线为对角线的两个矩形是否有重叠部分
        if(!(min(a.x,b.x)<=max(c.x,d.x)&&min(c.y,d.y)<=max(a.y,b.y)&&min(c.x,d.x)<=max(a.x,b.x)&&min(a.y,b.y)<=max(c.y,d.y))) return false;
       double u,v,w,z;                                                              //分别记录两个向量
       u=(c.x-a.x)*(b.y-a.y)-(b.x-a.x)*(c.y-a.y);
       v=(d.x-a.x)*(b.y-a.y)-(b.x-a.x)*(d.y-a.y);
       w=(a.x-c.x)*(d.y-c.y)-(d.x-c.x)*(a.y-c.y);
       z=(b.x-c.x)*(d.y-c.y)-(d.x-c.x)*(b.y-c.y);
       return (u*v<=eps&&w*z<=eps);
}
int main()
{
    int r,b;                //起点 终点
    scanf("%d%d",&r,&b);
    for(int i=0;i<r;i++)
        scanf("%lf%lf",&p[i].x,&p[i].y);
    for(int i=0;i<b;i++)
        scanf("%lf%lf",&q[i].x,&q[i].y);
    bool flag=false;
    if(r!=b) flag=false;
    else {
            int s[15];
            //进行排列
            for(int i=0;i<r;i++)
                s[i]=i;
            do{
                if(flag) break;
                //组建r条线段
                for(int i=0;i<r;i++)
                {
                    k[i].m=p[s[i]];
                    k[i].n=q[i];
                }
                bool f=true;
                for(int i=0;i<r-1;i++)
                    for(int j=i+1;j<r;j++)
                         if(solve(k[i].m,k[i].n,k[j].m,k[j].n)) {
                            f=false;
                            break;
                         }
                if(f) flag=true;
            }while(next_permutation(s,s+r));
    }
    if(flag) cout<<"Yes\n";
    else cout<<"No\n";
    return 0;
}

F1:在母串中寻求匹配

#include<bits/stdc++.h>
using namespace std;
const int maxn=100+5;
int a[maxn],c[10005];
int cnt=0,n;
int main()
{
    int m;
    scanf("%d%d",&n,&m);
    //文本串
    for(int i=0;i<n;i++)
        scanf("%d",&a[i]);
    int b[maxn],len=0;                  //寻找子串长度
    for(int i=0;i<m;i++)
    {
         scanf("%d",&b[i]);
         len+=b[i];
    }
     for(int i=0;i<m;i++)
    {
        for(int j=0;j<b[i];j++)
            c[cnt++]=i+1;
    }
    sort(c,c+cnt);
    /*for(int i=0;i<cnt;i++)
        cout<<c[i]<<" ";
    cout<<endl;*/
    bool flag=false;
    for(int i=0;i<n-len+1;i++)
    {
        int d[maxn],cnt1=0;
        for(int j=i;j<=i+len-1&&j<n;j++)
        {
            d[cnt1++]=a[j];
        }
        sort(d,d+cnt1);
        int x;
        for(x=0;x<cnt;x++)
            if(c[x]!=d[x]) break;
        if(x==cnt) flag=true;
        if(flag) break;
    }
    if(flag) cout<<"YES"<<endl;
    else cout<<"NO"<<endl;
    return 0;
}


阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页