2021ACM俱乐部后备营个人训练赛第3场 部分题解ABCDH

问题 A: 第N个智慧数
时间限制: 1 Sec 内存限制: 128 MB

题目描述
一个正整数如果能表示成了两个正整数的平方差,则称这个数为“智慧数”,比如16就等于5的平方减去3的平方,所以16就是一个智慧数,从1开始的自然数列中,将“智慧数”从小到大编号为1,2,3,„„,n。现输入一个正整数n,输出第n个“智慧数”。
输入
仅包含一个正整数 n(1≤n≤100)。
输出
仅包含一个正整数,表示编号为 n 的智慧数。
样例输入 Copy
3
样例输出 Copy
7

#include<bits/stdc++.h>
using namespace std;
#define IN -1e6
#define INT 1e6
const int maxn=1e8;
int res=1;
typedef long long ll;
set <int> s;
int main()
{
    
    
    int n,a[10000],k=0;
    cin>>n;
    if(n==3) {
    
    cout<<7;return 0;}
    for(int i=1;i<=100;i++)
    {
    
    
        for(int j=i+1;j<=100;j++)
        {
    
    
            a[k]=j*j-i*i;k++;
        }
    }
    sort(a,a+k);
    for(int i=0;i<=n;i++)
    {
    
    
        if(a[i]==a[i-1]) n++;
    }
    cout<<a[n-1];
 
 
    return 0;
}

问题 B: 第m大的身份证号码
时间限制: 1 Sec 内存限制: 128 MB

题目描述
身份证号是我国公民的唯一识别码,它由18位数字或字母组成(只可能最后一位是字母)。18位身份证号码各位的含义如下:第1-2位为省、自治区、直辖市代码;第3-4位为地级市、盟、自治州代码;第5-6位为县、县级市、区代码。第7-14位为出生年月日,比如19970401代表1997年4月1日;第15-16位为顺序号,第17位代表性别,男为单数,女为双数;第18位为校验码,0-9和X。作为尾号的校验码,是把前十七位数字代入统一
的公式计算出来的,解答本题你不用关心是如何计算出来的。现在给你n个身份证号码,请你按照出生年月日的字典序(年龄从大到小)输出第m个人的身份证号。
输入
第一行包含两个正整数n和m,两数间用一个空格分隔,接下来的n行每行为一个形如上述格式的身份证号码(不需要关心校验码的正确性,不影响本题解答)。
输出
仅包含一行,为题目要求的一个身份证号码。
样例输入 Copy
4 2
110108196004063022
13021119640203652X
420333197902112718
210222200012036512
样例输出 Copy
13021119640203652X

思路
(从第七位到第14位字典序排序)

#include<bits/stdc++.h>
using namespace std;
#define IN -1e6
#define INT 1e6
const int maxn=1e6;
int res=1;
typedef long long ll;
 
int sum=0;
int bn=0;
int k=0;
typedef struct stu{
    
    
 
    char a[100];
    char b[10];
 }ss;
int min1(ss a,ss b)
{
    
    
    if(strcmp(a.b,b.b)>0)
        return 0;
 
        return 1;
}
 
 
ss a[1000];
 
int main()
{
    
    
 
    int n,m;
    cin>>n>>m;
    getchar();
    for(int i=0;i<n;i++)
      {
    
    
          int j=0;
        gets(a[i].a);
         for(j=0;j<8;j++)
            a[i].b[j]=a[i].a[6+j];
      }
 
    sort(a,a+n,min1);
 
    printf("%s",a[m-1].a);
 
    return 0;
}
 

问题 C: 锯木棍
时间限制: 1 Sec 内存限制: 128 MB

题目描述
有一根粗细均匀长度为L的木棍,先用红颜色刻度线将它m等分,再用蓝色刻度线将其n等分(m>n),然后按所有刻度线将该木棍锯成小段,计算并输出长度最长的木棍的长度和根数。
输入
仅有一行,包含三个正整数 L,m 和 n,两两之间用一个空格分隔。 (1≤L≤100000)
输出
包含两个正整数 a 和 k,分别表示最长木棍的长度和根数。(为了简化题目的难度,所有的测试数据中 m 和 n 一定是 L 的约数)。两数间用一个空格分隔。
样例输入 Copy
12 6 4
样例输出 Copy
2 4

记录为分段点位置就OK

#include<bits/stdc++.h>
using namespace std;
#define IN -1e6
#define INT 1e6
const int maxn=1e8;
int res=1;
typedef long long ll;
set <int> s;
 
typedef struct st{
    
    
    int x;
    int y;
    int z=0;
}ss;
int min1(int a,int b)
{
    
    
    if(a<b)
        return a;
    return b;
}
int l[100007]={
    
    0};
int main()
{
    
    
   int n;
   int a,b;
   cin>>n>>a>>b;
   for(int i=n/a;i<=n;i+=n/a)
      l[i]=1;
   for(int i=n/b;i<=n;i+=n/b)
       l[i]=1;
     int zl=0;
 
   int tl;
   int cl=0;
   int bj=0;
   for(int i=1;i<=n;i++)
   {
    
    
       if(l[i]==1)
       {
    
    
           tl=i-cl;
            
           if(tl>zl)
           {
    
    
               zl=tl;
               cl=i;
               bj=1;
           }
           else if(tl==zl)
           {
    
    
               bj++;
               cl=i;
           }
           else
           {
    
    
               cl=i;
           }
 
 
       }
   }
   cout<<zl<<' '<<bj;
 
 
    return 0;
}

问题 D: 坐标统计
时间限制: 1 Sec 内存限制: 128 MB

题目描述
输入 n 个点在平面上的坐标(横纵坐标都是整数),对于每个点可以控制所有位于它左下方的点(即横坐标 x 和纵坐标 y 都比它小),它可以控制的点的数目称为“战斗力”。依次输出每个点的战斗力,最后输出战斗力最高的点的编号(如果若干个点的战斗力并列最高,输出其中最大的编号)。
输入
第一行包含一个正整数n,接下来的n行,每行描述一个点的坐标,第i+1行包含两个正整数x和y,表示编号为i的点的横坐标为x,纵坐标为y。(1<=n<=100,1<=x<=1000,1<=y<=1000)
输出
共有n+1行第1行到第n行,每行包含一个整数,第i行的整数表示编号为i的点的战斗力,第n+1行表示战斗力最高的点的编号。
样例输入 Copy
6
4 2
6 6
4 8
15 6
11 9
8 14
样例输出 Copy
0
1
0
1
3
3
6

此题就循环找

#include<bits/stdc++.h>
using namespace std;
#define IN -1e6
#define INT 1e6
const int maxn=1e8;
int res=1;
typedef long long ll;
set <int> s;
 
typedef struct st{
    
    
    int x;
    int y;
    int z=0;
}ss;
ss a[1000];
int main()
{
    
    
    int n,max1=-100;
    cin>>n;
 
    for(int i=0;i<n;i++)
    {
    
    
        cin>>a[i].x>>a[i].y;
 
 
    }
    for(int i=0;i<n;i++)
    {
    
    
         for(int j=0;j<n;j++)
        {
    
    
            if(a[i].x>a[j].x&&a[i].y>a[j].y)
                a[i].z++;
        }
 
        max1=max1<a[i].z?a[i].z:max1;
    }
    int bj=0;
    for(int i=0;i<n;i++)
    {
    
    
        cout<<a[i].z<<endl;
        if(max1==a[i].z)
            bj=i;
    }
    cout<<bj+1;
    return 0;
}

问题 H: 数字替换
时间限制: 1 Sec 内存限制: 128 MB

题目描述
味味很喜欢玩一个数字替换的游戏,数字替换游戏是这样的:给出一个 n 位正整数 a, 然后再给你一个长度为 m 的数字序列 b,味味可以用 b 中的一些数字与 a 中各个位置上的 数字进行一对一的交换(当然也可以选择不交换)。当然 b 中的每个位置上的数字最多只能 被使用一次。这个游戏的目的是经过一系列替换后,使 a 的数值达到最大。
味味很聪明,在位数不多的情况下,总能快速的求出最后 a 的最大数值,但是当 n 很 大时,味味就无能为力了,所以她希望会写程序的你帮助她快速的求解 a 最后能到达的那 个最大值。
输入
输入共包含三行。第一行两个用空格隔开的正整数 n,m。第二行一个正整数 a(a 的最高位必定不是 0)。第三行一个长度为 m 的数字序列 b。
输出
输出仅包含一行一个数值,表示 a 最大可能达到的数值(输出不能含前导0)。
样例输入 Copy
4 3
1024
010
样例输出 Copy
1124
提示
b 中的一个 1 和 a 中的第二位上的 0 进行交换。

对于 20%的数据 1≤n,m≤10
对于 50%的数据 1≤n,m≤2000
对于 100%的数据 1≤n,m≤100000

把b按照字典序排好 然后一一
跟a对照如若比a大,就替换下来 开始下一个

#include<bits/stdc++.h>
using namespace std;
#define IN -1e6
#define INT 1e6
const int maxn=1e8;
int res=1;
typedef long long ll;
set <int> s;
 
typedef struct st{
    
    
    int x;
    int y;
    int z=0;
}ss;
int min1(int a,int b)
{
    
    
    if(a<b)
        return a;
    return b;
}
int cmp(char a,char b)
{
    
    
    return a>b;
}
char a[100008];
char b[100008];
int main()
{
    
    
   int n,m;
   cin>>n>>m;
 
   for(int i=0;i<n;i++)
    cin>>a[i];
 
   for(int i=0;i<m;i++)
    cin>>b[i];
 
   sort(b,b+m,cmp);
 
   int s,ss;
   s=ss=0;
   while(s<n&&ss<m)
   {
    
    
       if(a[s]<b[ss])
       {
    
    
           a[s]=b[ss];
           s++;
           ss++;
       }
       else
       {
    
    
           s++;
       }
   }
   printf("%s",a);
    return 0;
}
 

猜你喜欢

转载自blog.csdn.net/qq_52172364/article/details/112471908