zoukankan      html  css  js  c++  java
  • 2018-2019赛季多校联合新生训练赛第五场(2018/12/14)补题题解

    A 【字符串】ISBN号码(字符串基础)

    字符串基础题,注意一下x的特判即可

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
      ios::sync_with_stdio(0);
      cin.tie(0);
      cout.tie(0);
      string a;
      int p=1,sum=0;
      cin>>a;
      for(int i=0;i<a.size()-1;i++)
      if(isdigit(a[i]))
      sum+=(a[i]-'0')*p++;
      sum%=11;
      if(sum==10)
      {
        if(a[a.size()-1]=='X')
        cout<<"Right";
        else
        {
          for(int i=0;i<a.size()-1;i++)
          cout<<a[i];
          cout<<'X';
        }
      }
      else
      {
        if(char(sum+'0')==a[a.size()-1])
        cout<<"Right";
        else
        {
          for(int i=0;i<a.size()-1;i++)
          cout<<a[i];
          cout<<char(sum+'0');
        }
      }
     
    }
    

    B 第N个智慧数(数学)

    打表题

    解法

    把所有的平方差都枚举一下

    for(int i=1;i<=n;i++)
    for(int j=1;j<i;j++)
    cout<<i*i-j*j;
    

    这样还会出现重复的项,并且还是乱序的,我是打出表来之后再把他们放到set中进行进行去重与排序然后输出即可

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int bk[]={这里是打表};
    int main()
    {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        set<int> st;
        for(int i=0;i<4950;i++)
        st.insert(bk[i]);
        int n,sum=0;
        cin>>n;
        for(auto it=st.begin();it!=st.end();it++)
        {
            sum++;
            if(sum==n)
            {
                cout<<*it;
                break;
            }
        }
    }
    

    C 第m大的身份证号码(字符串基础)

    这个把他们用个sort排序一下就可以了

    代码

    #include <bits/stdc++.h>
    using namespace std;
    string num[1666],num1[666];
    bool cmp(string a,string b)
    {
      string t1="",t2="";
      for(int i=6;i<=13;i++)
      t1+=a[i];
      for(int i=6;i<=13;i++)
      t2+=b[i];
      return t1<t2;
    }
    int main()
    {
      ios::sync_with_stdio(0);
      cin.tie(0);
      cout.tie(0);
      int n,k;
      cin>>n>>k;
      for(int i=0;i<n;i++)
      cin>>num[i];
      sort(num,num+n,cmp);
      cout<<num[k-1];
    }
    

    D 锯木棍(模拟)

    这个题直接模拟即可

    解法

    因为涂色,所以我们可以把这个木块当一个桶,涂色等于桶上的点放入了东西。因为涂两种颜色且两种颜色都是长度的约数,因此我们可以直接进行扫描

    第一遍扫描扫最大值

    第二遍扫描扫等于最大值的数量

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int bk[100015];
    int main()
    {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        int l,m,n,maxn=-1,sum=0,ans=0;
        cin>>l>>m>>n;
        int s1=l/m;
        int s2=l/n;
        for(int i=1;i<=l;i++)
        if(i%s1==0)
        bk[i]=1;
        for(int i=1;i<=l;i++)
        if(i%s2==0)
        bk[i]=1;
        for(int i=1;i<=l;i++)
        {
          if(bk[i]==0)
          sum++;
          else
          {
            sum++;
            maxn=max(maxn,sum);
            sum=0;
          }
        }
        for(int i=1;i<=l;i++)
        {
          if(bk[i]==0)
          sum++;
          else
          {
            sum++;
            if(sum==maxn)
            ans++;
            sum=0;
          }
        }
        cout<<maxn<<" "<<ans;
    }
    

    E 坐标统计(基础编程能力)

    直接放入然后扫描比较即可

    代码

    #include <bits/stdc++.h>
    using namespace std;
    struct node
    {
      int x,y;
    }zb[10000];
    int sum[10000];
    int main()
    {
      ios::sync_with_stdio(0);
      cin.tie(0);
      cout.tie(0);
      int n,maxn=-1,id;
      cin>>n;
      for(int i=0;i<n;i++)
      cin>>zb[i].x>>zb[i].y;
      for(int i=0;i<n;i++)
      for(int j=0;j<n;j++)
      if(zb[j].x<zb[i].x&&zb[j].y<zb[i].y)
      sum[i]++;
      for(int i=0;i<n;i++)
      {
        if(sum[i]>=maxn)
        {
          maxn=sum[i];
          id=i+1;
        }
        cout<<sum[i]<<"
    ";
      }
      cout<<id;
    }
    

    F 打印月历(基础编程能力)

    可能这个题分到基础编程能力有点感觉不大合适,但是这个题确实没有别的什么难的知识点只是需要注意一些地方

    解法

    ①首先就是这个闰年的问题,闰年的2月还平年的2月是不一样的

    ②然后是计算这月距离第一个月的第一天有几天

    ③然后推出这个月的第一天是在星期几

    int t=(sum)%7;
      int day=(n+t-1)%7+1;
    

    其中day变量就是星期几

    ④之后再算出这个月具体多少天,这个还得分闰年和平年

    ⑤然后按照1到这个月的天数输出即可(这里之前还要把那些空格打印出来)

    ⑥注意第一行一定没有空行要不格式错误(测试数据 2015 2 4)

    ⑦还有数字用%-4d

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int month[]={0,31,0,31,30,31,30,31,31,30,31,30,31};
    int main()
    {
      /*ios::sync_with_stdio(0);
      cin.tie(0);
      cout.tie(0);*/
      int y,m,n,yn;
      cin>>y>>m>>n;
      cout<<"S   M   T   W   T   F   S
    ";
      if(y%4==0&&y%100!=0||y%400==0)
      yn=1;
      else
      yn=0;
      int c=m-1,mth,sum=0;
      for(int i=1;i<c+1;i++)
      {
        if(i==2)
        {
          if(yn)
          sum+=29;
          else
          sum+=28;
        }
        sum+=month[i];
      }
      int t=(sum)%7;
      int day=(n+t-1)%7+1;
      for(int i=0;i<(day%7)*4;i++)
      cout<<" ";
      if(m==2)
      {
        if(yn)
        mth=29;
        else
        mth=28;
      }
      else
      mth=month[m];
      int ft=1;
      for(int i=1;i<=mth;i++)
      {
        if(day==7)
        {
          if(!ft)
          cout<<"
    ";
          day=0;
        }
        printf("%-4d",i);
        day++;
        ft=0;
      }
    }
    

    G 分割绳子(二分查找)

    这个地方比赛的时候,都已经做出来了,就是因为二分查找带小数的东西有些细节不会找,导致的出现了问题

    对于小数点的精度问题,我们不能单纯的用l<=r而是用带精度的

    这个题我们要精确到小数点后两位,那么我们可以用

    while(l<=r-0.001)
    //do something
    

    其中mid也是double的,之前l=mid+1也变成了l=mid+0.001 r也相同的道理

    这个题原题应该没有什么问题吧,裸二分查找

    判断函数也是判断一下当前mid值能分割出几个绳子即可

    代码

    #include <bits/stdc++.h>
    using namespace std;
    double num[1005];
    int n,k;
    int isok(double m)
    {
      int sum=0;
      for(int i=0;i<n;i++)
      sum+=num[i]/m;
      return sum>=k;
    }
    int main()
    {
      ios::sync_with_stdio(0);
      cin.tie(0);
      cout.tie(0);
      double l=0,r;
      cin>>n>>k;
      for(int i=0;i<n;i++)
      cin>>num[i],r=max(r,num[i]);
      while(l<=r-0.001)
      {
        double mid=(l+r)/2;
        if(isok(mid))
        l=mid+0.001;
        else
        r=mid-0.001;
      }
      printf("%.2f",l-0.001);
    }
    

    H 换座位(语法基础)

    排序一次跟原来比较一下看哪里不一样了

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int num[666],num1[666];
    int main()
    {
      ios::sync_with_stdio(0);
      cin.tie(0);
      cout.tie(0);
      int n,sum=0;
      cin>>n;
      for(int i=0;i<n;i++)
      cin>>num[i],num1[i]=num[i];
      sort(num,num+n);
      for(int i=0;i<n;i++)
      if(num[i]!=num1[i])
      sum++;
      cout<<sum;
    }
    

    I 找M进制数(字符串基础)

    这个题我还因为细节问题罚时两次

    需要注意的细节

    ①十进制以下是否出现了字母或者大于等于当前进制的数

    ②十进制以上是否出现了大于等于当前进制的字母

    ③第一位数字是否为0(听说这个数据中好像没有给出)、

    代码

    #include <bits/stdc++.h>
    using namespace std;
    struct node
    {
      int x,y;
    }zb[10000];
    int sum[10000];
    string st[100005];
    int main()
    {
      ios::sync_with_stdio(0);
      cin.tie(0);
      cout.tie(0);
      int n,maxn=-1,id;
      cin>>n>>id;
      int ans=n;
      for(int i=0;i<n;i++)
      cin>>st[i];
      for(int i=0;i<n;i++)
      for(int j=0;j<st[i].size();j++)
      {
        if(st[i][0]=='0')
        {
          ans--;
          break;
        }
        if(id<=10)
        {
          if(isalpha(st[i][j]))
          {
            ans--;
            break;
          }
          if(isdigit(st[i][j]))
          {
            if(st[i][j]-'0'>id-1)
            {
              ans--;
              break;
            }
          }
        }
        if(id>10)
        {
          if(isalpha(st[i][j]))
          {
            if(st[i][j]>'A'+id-11)
            {
              ans--;
              break;
            }
          }
        }
      }
      cout<<ans;
    }
    

    J 循环小数(字符串模拟)

    这个题并不难啊,比起紫书上那个90年代的acm世界决赛的真题来说还是太嫩了点

    解法

    ①找出循环节前的小数

    ②找出循环节

    ③把循环节循环多次加到循环节前的小数后面(这里一定要比给定的要找的位数要多)

    ④按照要求输出即可

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int bk[100015];
    int main()
    {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        int n,f=0,ff=0;
        cin>>n;
        string a,nu="",xh="";
        cin>>a;
        for(int i=0;i<a.size();i++)
        {
          if(a[i]=='.')
          f=1;
          if(a[i]=='(')
          ff=1;
          if(f&&!ff)
          {
              if(isdigit(a[i]))
              nu+=a[i];
          }
          if(f&&ff)
          {
            if(isdigit(a[i]))
            xh+=a[i];
          }
        }
        for(int i=0;i<100005;i++)
        nu+=xh;
        cout<<nu[n-1];
    }
    

    K 单纯质因数(数论)

    当时一直打表还不知道哪里打错了,实际上这个题可以直接暴力去做

    我这里又学到了一种O(N根号(N))的分解质因数的算法

    这里可以直接用朴素的思想,如果他没有相同的质因数,那么肯定就是把所有的质因数乘起来就等于原来的说

    好,我们用这个思想去做,从2到n每个数枚举一遍看他是不是质因数

    然后就超时了,因为O(N*N)对于1e5来说还是太大了(当然你可以打表啊,打出5万以内的素数表)

    这里介绍一种O(N*根号(N))的分解因数的方法

    for(int j=2;j*j<=i;j++)
    {
        if(i%j==0)
        {
            if(isp(j))
            sum*=j;
            if(i/j!=j&&isp(i/j))
            sum*=(i/j);
        }
    }
    

    这里第一个条件就是朴素的找到质因数,第二个条件就是如果这个数除以找到的这个数不等于原来的(符合条件一不同的因数)且是质数(符合条件二是质因数)

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int isp(int n)
    {
      for(int i=2;i*i<=n;i++)
      if(n%i==0)
      return 0;
      return 1;
    }
    int main()
    {
      ios::sync_with_stdio(0);
      cin.tie(0);
      cout.tie(0);
      int n;
      cin>>n;
      for(int i=6;i<=n;i++)
      {
        if(isp(i))
        continue;
        int jk=1;
        for(int j=2;j*j<=i;j++)
        if(i%j==0)
        {
          if(isp(j))
          jk*=j;
          if(i/j!=j&&isp(i/j))
          jk*=(i/j);
          if(jk==i)
          {
            cout<<i<<" ";
            break;
          }
        }
      }
    }
    

    L 安装饮水机(贪心)

    实际上这个就是经典的区间选点问题的贪心,把给的数据化成一个一个的区间然后贪心即可

    代码

    #include <bits/stdc++.h>
    using namespace std;
    struct node
    {
      int l,r;
    }num[10000];
    bool cmp(node a,node b)
    {
      return a.r==b.r?a.l>b.l:a.r<b.r;
    }
    int main()
    {
      ios::sync_with_stdio(0);
      cin.tie(0);
      cout.tie(0);
      int n;
      cin>>n;
      for(int i=0;i<n;i++)
      {
        int t1,t2;
        cin>>t1>>t2;
        int l=t1-t2;
        int r=t1+t2;
        if(l<0)
        l=0;
        num[i].l=l;
        num[i].r=r;
      }
      sort(num,num+n,cmp);
      int now=num[0].r,ans=1;
      for(int i=1;i<n;i++)
      if(num[i].l>now)
      {
        ans++;
        now=num[i].r;
      }
      cout<<ans;
    }
    

    M 分木块(语法基础)

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int num[666],num1[666];
    int main()
    {
      ios::sync_with_stdio(0);
      cin.tie(0);
      cout.tie(0);
      int n,sum=0,r1=0,r2=0,r3=0;
      cin>>n;
      for(int i=0;i<n;i++)
      {
        int t,ans1=0,ans2=0,ans3=0;
        cin>>t;
        ans1+=t/100;
        t%=100;
        ans2+=t/10;
        t%=10;
        ans3+=t;
        r1+=ans1;
        r2+=ans2;
        r3+=ans3;
      }
      cout<<r1<<"
    "<<r2<<"
    "<<r3;
    }
    

    N 活动人数(语法基础)

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int num[1666],num1[666];
    int main()
    {
      ios::sync_with_stdio(0);
      cin.tie(0);
      cout.tie(0);
      int n,sum=0,r1=0,r2=0,r3=0,l,k;
      cin>>n>>l>>k;
      for(int i=0;i<n;i++)
      cin>>num[i];
      sort(num,num+n);
        for(int i=0;i<n;i++)
        if(1)
        {
          if(l>=num[i])
          {
            sum++;
            l+=k;
          }
        }
        cout<<sum;
    }
    
  • 相关阅读:
    JDBC编程获取数据库连接(mysql 8.0版本以上)
    opnet启动和debug模式提示warning:找不到目录
    打开Word时默认使标题下的内容折叠起来
    OPNET进程编译器无法编译:Compilation failed || VS2017或VS2019与opnet的安装注意
    IDEA中使用单元测试方法@Test
    C/C++字符数组、字符串、字符串指针、字符串指针数组的访问操作(一维数组)
    C/C++字符数组、字符串、字符串指针、字符串指针数组的声明和初始化操作(一维数组)
    安装C++集成开发环境CodeBlock(带MinGW)
    Express
    模块化
  • 原文地址:https://www.cnblogs.com/baccano-acmer/p/10122339.html
Copyright © 2011-2022 走看看