2017年天梯初赛真题

这篇博客包含多个编程题目,包括根据出生年份和目标年份找出符合条件的年份,统计点赞记录以分析用户特性,按古风格式排版文字,以及通过用户关注和点赞行为推测可能的悄悄关注对象。每个题目都提供了输入输出样例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.

以上是新浪微博中一奇葩贴:“我出生于1988年,直到25岁才遇到4个数字都不相同的年份。”也就是说,直到2013年才达到“4个数字都不相同”的要求。本题请你根据要求,自动填充“我出生于y年,直到x岁才遇到n个数字都不相同的年份”这句话。

输入格式:

输入在一行中给出出生年份y和目标年份中不同数字的个数n,其中y在[1, 3000]之间,n可以是2、或3、或4。注意不足4位的年份要在前面补零,例如公元1年被认为是0001年,有2个不同的数字0和1。

输出格式:

根据输入,输出x和能达到要求的年份。数字间以1个空格分隔,行首尾不得有多余空格。年份要按4位输出。注意:所谓“n个数字都不相同”是指不同的数字正好是n个。如“2013”被视为满足“4位数字都不同”的条件,但不被视为满足2位或3位数字不同的条件。

输入样例1:

1988 4

输出样例1:

25 2013

输入样例2:

1 2

输出样例2:

0 0001

顺着年份找就好啦,然后每年都统计一下不一样的位数,当年份小于1000时要把0也标记为存在

输出的时候要注意前面补0

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<vector>
#include<map>
using namespace std;
#define maxn 100005
#define eps 1e-6
map<int,int>q;
int w,p;
int main()
{
    int y,n;
    scanf("%d %d",&y,&n);
    int old = 0;
    int flag = 0;
    for(int i = y; ; i ++)
    {
        q.clear();
        int temp = i;
        flag = 0;
        if(temp<1000)
            q[0] = 1;
        while(temp)
        {
            int k = temp%10;
            q[k] = 1;
            temp = temp/10;
        }
        if(q.size()==n)
        {
            printf("%d %04d",old,i);
            break;
        }
        old++;
    }
}

微博上有个“点赞”功能,你可以为你喜欢的博文点个赞表示支持。每篇博文都有一些刻画其特性的标签,而你点赞的博文的类型,也间接刻画了你的特性。本题就要求你写个程序,通过统计一个人点赞的纪录,分析这个人的特性。

输入格式:

输入在第一行给出一个正整数N(≤1000),是该用户点赞的博文数量。随后N行,每行给出一篇被其点赞的博文的特性描述,格式为“K F​1​​⋯F​K​​”,其中1≤K≤10,F​i​​(i=1,⋯,K)是特性标签的编号,我们将所有特性标签从1到1000编号。数字间以空格分隔。

输出格式:

统计所有被点赞的博文中最常出现的那个特性标签,在一行中输出它的编号和出现次数,数字间隔1个空格。如果有并列,则输出编号最大的那个。

输入样例:

4
3 889 233 2
5 100 3 233 2 73
4 3 73 889 2
2 233 123

输出样例:

233 3

用map标记一下~然后遍历一遍

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
map<int,int>q;
int main()
{
    int n;
    scanf("%d",&n);
    int maxx = 0,minn = 1005;
    for(int i = 0; i < n; i ++)
    {
        int k;
        scanf("%d",&k);
        for(int j = 0; j < k; j ++)
        {
            int x;
            scanf("%d",&x);
            minn = min(x,minn);
            maxx = max(x,maxx);
            q[x] ++;
        }
    }
    int cnt = 0;
    int index = 0;
    map<int,int>::iterator it;
    for(it = q.begin(); it != q.end(); it ++)
    {
        if(it->second>cnt)
        {
            cnt = it->second;
            index = it->first;
        }
        else if(it->second == cnt)
        {
            if(it->first>index)
            {
                index = it->first;
            }
        }
    }
    printf("%d %d",index,cnt);
    return 0;
}

中国的古人写文字,是从右向左竖向排版的。本题就请你编写程序,把一段文字按古风排版。

输入格式:

输入在第一行给出一个正整数N(<100),是每一列的字符数。第二行给出一个长度不超过1000的非空字符串,以回车结束。

输出格式:

按古风格式排版给定的字符串,每列N个字符(除了最后一列可能不足N个)。

输入样例:

4
This is a test case

输出样例:

asa T
st ih
e tsi
 ce s

行数为n,列数为col;

col的计算方式,字符串长度/行数,如果余数不为0,那么col++

接下来根据推算可知,应该是从最后一列开始赋值的。

根据规律写出表达式即可

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
string s;
char ch[1005][1005];
int main()
{
    int n;
    scanf("%d ",&n);
    getline(cin,s);
    int len = s.length();
    int col = len/n;
    if(len%n)
        col++;
    for(int i = 0; i < n; i ++)
        for(int j = 0; j < col; j ++)
            ch[i][j] = ' ';
    int cnt = 0;
    int k = 0;
    for(int i = 0; i < len; i ++)
    {
        ch[k][col-cnt-1] = s[i];
        k++;
        if(k==n)
        {
            k = 0;
            cnt++;
        }
    }
    for(int i = 0; i < n; i ++)
    {
        for(int j = 0; j < col; j ++)
            printf("%c",ch[i][j]);
        printf("\n");
    }

    return 0;
}

新浪微博上有个“悄悄关注”,一个用户悄悄关注的人,不出现在这个用户的关注列表上,但系统会推送其悄悄关注的人发表的微博给该用户。现在我们来做一回网络侦探,根据某人的关注列表和其对其他用户的点赞情况,扒出有可能被其悄悄关注的人。

输入格式:

输入首先在第一行给出某用户的关注列表,格式如下:

人数N 用户1 用户2 …… 用户N

其中N是不超过5000的正整数,每个用户ii=1, ..., N)是被其关注的用户的ID,是长度为4位的由数字和英文字母组成的字符串,各项间以空格分隔。

之后给出该用户点赞的信息:首先给出一个不超过10000的正整数M,随后M行,每行给出一个被其点赞的用户ID和对该用户的点赞次数(不超过1000),以空格分隔。注意:用户ID是一个用户的唯一身份标识。题目保证在关注列表中没有重复用户,在点赞信息中也没有重复用户。

输出格式:

我们认为被该用户点赞次数大于其点赞平均数、且不在其关注列表上的人,很可能是其悄悄关注的人。根据这个假设,请你按用户ID字母序的升序输出可能是其悄悄关注的人,每行1个ID。如果其实并没有这样的人,则输出“Bing Mei You”。

输入样例1:

10 GAO3 Magi Zha1 Sen1 Quan FaMK LSum Eins FatM LLao
8
Magi 50
Pota 30
LLao 3
Ammy 48
Dave 15
GAO3 31
Zoro 1
Cath 60

输出样例1:

Ammy
Cath
Pota

输入样例2:

11 GAO3 Magi Zha1 Sen1 Quan FaMK LSum Eins FatM LLao Pota
7
Magi 50
Pota 30
LLao 48
Ammy 3
Dave 15
GAO3 31
Zoro 29

输出样例2:

Bing Mei You
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
struct node{
    string name;
    int num;
}s[100005];
int cmp(struct node a,struct node b)
{
    return a.name<b.name;

}
map<string,int>q;
int main()
{
    int n;
    scanf("%d",&n);
    for(int i = 0; i < n; i ++)
    {
        getchar();
        string temp;
        cin>>temp;
        q[temp] = 1;
    }
    int m;
    scanf("%d",&m);
    int sum = 0;
    for(int i = 0; i < m; i ++)
    {
        getchar();
        cin>>s[i].name>>s[i].num;
        sum += s[i].num;
    }
    double ave = 1.0*sum/m;
    sort(s,s+m,cmp);
    int flag = 0;
    
    for(int i = 0; i < m; i ++)
    {
        if(1.0*s[i].num>=ave&&!q[s[i].name])
        {
            cout<<s[i].name<<endl;
            flag = 1;
        }
    }
    if(!flag)
        printf("Bing Mei You");
    return 0;
}

 

一门武功能否传承久远并被发扬光大,是要看缘分的。一般来说,师傅传授给徒弟的武功总要打个折扣,于是越往后传,弟子们的功夫就越弱…… 直到某一支的某一代突然出现一个天分特别高的弟子(或者是吃到了灵丹、挖到了特别的秘笈),会将功夫的威力一下子放大N倍 —— 我们称这种弟子为“得道者”。

这里我们来考察某一位祖师爷门下的徒子徒孙家谱:假设家谱中的每个人只有1位师傅(除了祖师爷没有师傅);每位师傅可以带很多徒弟;并且假设辈分严格有序,即祖师爷这门武功的每个第i代传人只能在第i-1代传人中拜1个师傅。我们假设已知祖师爷的功力值为Z,每向下传承一代,就会减弱r%,除非某一代弟子得道。现给出师门谱系关系,要求你算出所有得道者的功力总值。

输入格式:

输入在第一行给出3个正整数,分别是:N(≤10​5​​)——整个师门的总人数(于是每个人从0到N−1编号,祖师爷的编号为0);Z——祖师爷的功力值(不一定是整数,但起码是正数);r ——每传一代功夫所打的折扣百分比值(不超过100的正数)。接下来有N行,第i行(i=0,⋯,N−1)描述编号为i的人所传的徒弟,格式为:

K​i​​ ID[1] ID[2] ⋯ ID[K​i​​]

其中K​i​​是徒弟的个数,后面跟的是各位徒弟的编号,数字间以空格间隔。K​i​​为零表示这是一位得道者,这时后面跟的一个数字表示其武功被放大的倍数。

输出格式:

在一行中输出所有得道者的功力总值,只保留其整数部分。题目保证输入和正确的输出都不超过10​10​​。

输入样例:

10 18.0 1.00
3 2 3 5
1 9
1 4
1 7
0 7
2 6 1
1 8
0 9
0 4
0 3

输出样例:

404
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
#define maxn 100005
int n;
double z,r;
int a[maxn];
vector<int>q[maxn];
double dfs(int x,int t)
{
    double s = 0;
    if(!q[x].size())
        s += a[x]*z*pow(1-r/100,t);
    else
    {
        for(int i = 0; i < q[x].size(); i ++)
            s += dfs(q[x][i],t+1);
    }
    return s;
}
int main()
{
    scanf("%d %lf %lf",&n,&z,&r);
    for(int i = 0; i < n; i ++)
    {
        int k;
        scanf("%d",&k);
        if(!k)
            scanf("%d",&a[i]);
        else
        {
            for(int j = 0; j < k; j ++)
            {
                int x;
                scanf("%d",&x);
                q[i].push_back(x);
            }
        }
    }
    double ans = dfs(0,0);
    printf("%lld",(long long int)ans);
}

 

### 天梯真题及相关编程题目 天梯赛是个旨在考察学生基础算法能力与编程技巧的竞赛,其题目覆盖范围广泛,从简单的输入输出到复杂的动态规划均有涉及[^2]。以下是几类常见的天梯赛题目及其特点: #### 输入输出与简单逻辑 这类题目通常用于测试选手的基础语法掌握情况以及基本逻辑思维能力。例如,在某些比赛中可能会要求判断两个人谁先醉倒并统计另人的饮酒量[^3]。 ```cpp #include <iostream> using namespace std; int main() { int a_max, b_max; cin >> a_max >> b_max; char who = ' '; int count = 0; while (true) { int temp; cin >> temp; if (temp == -1) break; if (who != 'B') { a_max -= temp; if (a_max <= 0 && who != 'A') { who = 'A'; continue; } } if (who != 'A') { b_max -= temp; if (b_max <= 0 && who != 'B') { who = 'B'; continue; } } count += temp; } cout << ((who == 'A') ? "B" : "A") << endl; cout << count << endl; } ``` 上述代码片段展示了如何通过循环模拟两人轮流喝酒的过程,并最终判定哪方率先达到极限。 #### 数组操作与排序 对于稍复杂点的操作,则可能涉及到数组元素的排列组合或者重复项去除等问题。下面给出了种实现方法来完成两个列表合并后再去重的任务[^4]。 ```cpp #include <bits/stdc++..h> using namespace std; const int N = 2e4 + 5; int a[N]; int main(){ ios::sync_with_stdio(false); cin.tie(0); int n,m; cin>>n; for(int i=0;i<n;++i){ cin>>a[i]; } cin>>m; for(int j=0;j<m;++j){ cin>>a[j+n]; } sort(a,a+n+m); int l=unique(a,a+n+m)-a; for(int k=0;k<l-1;++k){ cout<<a[k]<<" "; } cout<<a[l-1]<<endl; return 0; } ``` 此段代码利用C++标准库中的`sort()`函数对整个序列进行了升序整理,随后调用了`unique()`函数删除相邻相同的数值。 #### 数据结构应用 随着难度提升,还会遇到关于栈、队列等高级数据类型的运用场景。这些都需要参赛者具备扎实的知识功底才能顺利解答出来。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值