icpc上海站2020部分题解

第一次icpc比赛,最后是以3题300多名的成绩直接打铁,很可惜,D题赛后才知道是精度的问题,不然估计可以拿铜。
从比赛中也能得到很多经验与教训。

经验:

1.选好赛区,少打两年。这次站除去打星队都有600多队,只有210个牌,听说济南站只有500队牌子数跟上海站一样,枯了。
2.这次思维题有足足5题,全做了可以到银牌,以后要加强手速和思维题的锻炼,可以多打cf。
3.数学题偏多。前5题:G B M D I 中,有G D I 都是数学题,注重公式推导,数学运算,这方面以后要加强锻炼。

反思

个人反思:
1.签到题推公式速度慢
2.一开始B题很久没思路,有点自暴自弃,M题莽了几发,应该交题之前多测几组数据。
3.英语读题能力还要锻炼

团队反思:
1.个人能力普遍较低,前期不能多开快速a掉思维题
2.英语读题能力普遍较低

B Mine Sweeper II

将图翻转后发现,和与原来一样,构造的时候只需构造成与原来一样或者翻转,都不满足输出-1 。一开始还以为是搜索…

#include <bits/stdc++.h>

using namespace std;
char map1[1005][1005],map2[1005][1005];
int m,n,a;

int main()
{
   scanf("%d %d",&n,&m);
    a=m*n/2;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        scanf(" %c",&map1[i][j]);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf(" %c",&map2[i][j]);
    int ans=0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            if(map1[i][j]!=map2[i][j])ans++;
        }
    if(ans<=n*m/2)
    {
        for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++)
            printf("%c",map1[i][j]);
        printf("\n");}
        return 0;

    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            if(map1[i][j]=='.')map1[i][j]='X';
            else map1[i][j]='.';
        }
    ans=0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            if(map1[i][j]!=map2[i][j])ans++;
        }
    
    if(ans<=n*m/2)
    {
        for(int i=1;i<=n;i++){


        for(int j=1;j<=m;j++)
            printf("%c",map1[i][j]);
        printf("\n");}
        return 0;
    }
    printf("-1\n");
    return 0;
}

C Sum of Log

D Walker

在这里插入代码片

G Fibonacci
签到题,等差数列求和

#include <bits/stdc++.h>

using namespace std;
long long n,m,ans,l;
int main()
{
    scanf("%lld",&n);
    long long z = n/3;
    z--;
    long long yu = n%3;
    ans = (5*z+9)*z/2+2;
    ans+=(yu*(z+1));
    cout<<ans<<endl;
    return 0;
}

I Sky Garden
暴力即可,枚举每一层,每一层上的点都是一样的,然后枚举每一层上的每一个点,复杂度O(nnm),

#include <bits/stdc++.h>

using namespace std;

const double pi=acos(-1);
int main()
{
    double ans=0;
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        double tmp_sum=0;
        for(int j=i+1;j<=n;j++)
        {
            for(int k=1;k<m;k++)
            {
                double tmp=k*1.0/m*pi;
                if(tmp>2.0)tmp=2.0;
                tmp_sum+=((i*tmp+(j-i))*2);
            }
            tmp_sum+=2*j;
        }
        ans+=tmp_sum*(2*m);
        tmp_sum=0;
        for(int k=1;k<m;k++)
        {
            double tmp=k*1.0/m*pi;
            if(tmp>2.0)tmp=2.0;
            tmp_sum+=i*tmp;
        }
        if(m==1)
            ans+=(tmp_sum*2*m+m*2*i);
        else ans+=(tmp_sum*2*m+m*4*i);
    }
    printf("%.15lf\n",ans);
    return 0;
}

M Gitignore
将不需删除的标记,已删除了的也标记,遍历到已删除的文件夹,直接看下一个,遍历到不需删除的忘后面的文件夹看,文件名不能标记,遍历到文件名时直接ans+1 。
删除了的需要标记前缀,不需删除的将前缀都标记,因为文件夹名可以相同,一开始只标记文件夹名wa了几发,然后莽交wa了几发。

#include <bits/stdc++.h>

using namespace std;
map<string,int>del,mp;
int main()
{
    int t;
    string a[105];
    cin>>t;
    while(t--)
    {
        mp.clear();
        del.clear();
        int n,m,ans=0;
        cin>>n>>m;
        for(int i=0;i<n;i++)
        {
            cin>>a[i];
        }
        for(int i=0;i<m;i++)
        {
            string b;
            cin>>b;
            int last=0;
            for(int j=0;j<b.length();j++)
            {
                if(b[j]=='/')
                {
                    string c=b.substr(0,j+1);
                    mp[c]=1;
                    last = j+1;
                }
            }
        }
        int len;
        for(int i=0;i<n;i++)
        {
            int last = 0;
            len = a[i].length();
            for(int j=0;j<=len;j++)
            {
                if(j==len)
                {
                    ans++;
                }
                if(a[i][j]=='/')
                {
                    string c=a[i].substr(0,j+1);
                    last =j+1;
                    if(del[c]==1)break;

                    if(mp[c]==1)
                    {
                        continue;
                    }
                    else
                    {
                        ans++;
                        del[c]=1;
                        break;
                    }
                }
            }

        }
        cout<<ans<<endl;
    }
    return 0;
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值