算法竞赛入门【码蹄集进阶塔335题】(MT2026-2050)


文章目录

  • ​​算法竞赛入门【码蹄集进阶塔335题】(MT2026-2050)​​
  • ​​前言​​
  • ​​为什么突然想学算法了?​​
  • ​​为什么选择码蹄集作为刷题软件?​​
  • ​​目录​​
  • ​​1. MT2026 二维坐标点移动​​
  • ​​2. MT2027 一秒成零​​
  • ​​3. MT2028 小码哥的计划表​​
  • ​​4. MT2029 小码哥的跳棋游戏​​
  • ​​5. MT2030 邮箱地址​​
  • ​​6. MT2031 排队​​
  • ​​7. MT2032 建立数据库​​
  • ​​8. MT2033 碰碰车​​
  • ​​9. MT2034 竖直打印机​​
  • ​​10. MT2035 伯兰语​​
  • ​​11. MT2036 移水造海​​
  • ​​12. MT2037 奇怪的和​​
  • ​​13. MT2038 字符矩阵​​
  • ​​14. MT2039 换换换​​
  • ​​15. MT2040 银行账户​​
  • ​​16. MT2041 三角形的个数​​
  • ​​17. MT2042 硬币塔​​
  • ​​18. MT2043 数字问题​​
  • ​​19. MT2044 字符串的解码​​
  • ​​20. MT2045 河内双塔​​
  • ​​21. MT2046 斐波那契,但是是字符串​​
  • ​​22. MT2047 巨大的错误​​
  • ​​23. MT2048 距离平方和​​
  • ​​24. MT2049 三连​​
  • ​​25. MT2050 运动会进行中​​
  • ​​结语​​

前言

为什么突然想学算法了?

> 用较为“官方”的语言讲,是因为算法对计算机科学的所有分支都非常重要。 在绝大多数的计算机科学分支领域中,要想完成任何实质性的工作,理解算法的基础知识并掌握与算法密切相关的数据结构知识是必不可少的。
> 但从实际而言,是因为当下快到了考研和找工作的年纪(ಥ_ಥ),无论走哪一条路,都不免需要一些相对丰富的算法知识,是故,便产生了一个暑假速成算法的计划,可能对于像我这种算法竞赛小白而言,几乎很难,但我仍然还是想尝试一下,毕竟,梦想还是要有的,万一实现了呢?~( ̄▽ ̄~)~

算法竞赛入门【码蹄集进阶塔335题】(MT2026-2050)_数据结构


为什么选择码蹄集作为刷题软件?

码蹄集,是在全国高等学校计算机教学与产业实践资源建设专家委员会(TIPCC) 指导下建设的,其依托全国各大名校计算机系和清华大学出版社等单位的强大资源,旨在为计算机学习爱好者提供全面和权威的计算机习题。

算法竞赛入门【码蹄集进阶塔335题】(MT2026-2050)_c++_02


目录

1. MT2026 二维坐标点移动

(1)题目描述
给定一个N* M的二维坐标矩阵A,并且给定一个整数K,K表示移动步数,矩阵A中的所有点A[][j]的移动操作如下:

1.A[i][j]移动到A[i][j+1](j≤m -2)
2.A[i][m -1]移动到A[i+1][0](i≤n -2)
3.A[n - 1][m-1]移动到A[0][0]

最后输出移动了K次后新的二维坐标矩阵A 。

格式

输入格式:
第一行两个整数N, M(N ,M ≤50)
接下来N行,每行M个数,即A[i][j](0<i<N,0≤j<M ,-1000 ≤A[i][j]≤1000)
最后一行一个整数K(0≤K ≤100)
.
输出格式: N行,每行M个数,即修改之后的A[][j](0<i<N,0≤j<M ,—1000 ≤ A[i][i]≤1000) .

样例1

输入:
3 3
1 2 3
30 40 50
10 20 30
2
.
输出:
20 30 1
2 3 30
40 50 10

备注:

其中: 1≤N ,M ≤50,-1000≤ A[i][i]≤1000,0≤K ≤1000

(2)参考代码

#include<bits/stdc++.h> 

using namespace std;

int main( )
{
int n,m;
cin>>n>>m;
deque<int> a(n*m);
for(int i=0;i<n*m;i++) cin>>a[i];
int k;
cin>>k;
k%=n*m;
for(int i=0;i<k;i++){
a.push_front(a.back());
a.pop_back();
}
for(int i=0;i<n*m;){
cout<<a[i]<<" ";
i+=1;
if(i%m==0) cout<<endl;
}
return 0;
}

2. MT2027 一秒成零

(1)题目描述
给定一个正整数n ,请写一个函数Steps ,将n通过以下操作变成0,并且返回操作次数。

n为偶数,则n =n/2 ;
n为奇数,则n =n- 1。

格式

输入格式: n为偶数,则n =n/2 ;n为奇数,则n =n- 1。
.
输出格式: 输出操作次数

样例1

输入: 14
.
输出: 6

(2)参考代码

class Solution(object):
def Steps(self,n):
res=0
while n>0:
if n%2==0:
n //= 2
else:
n -= 1
res += 1
return res

def main():
#code here
n = int(input())
S = Solution()
res = S.Steps(n)
print(res)


if __name__ == '__main__':
main();

3. MT2028 小码哥的计划表

(1)题目描述
小码哥的寒假有Ⅳ天,他做了一个计划表,计划每天做若干数分题目,但是为了平衡每天的任务量,小码哥决定调整一下他的计划表。他首先设定了每天做题数目的上限R和下限L,然后他准备做一些调整,使得每天的题目数量A;满足L≤A≤R。每次调整小码哥可以把某一天的某些题目换到另一天,每次操作只能移动一道题目。

小码哥请你帮忙算一算需要的最小操作数。


格式

输入格式:
第一行一个正整数N,表示计划表的总天数;
第二行Ⅳ个整数,表示计划表初始每天的题目数;
第三行两个整数L,R。
.
输出格式: 一个数,表示最小的操作数,如果不能满足题目条件输出-1。

样例1

输入:
2
10 20
10 15
.
输出: 5

备注:

1 ≤n ≤100000,1≤ Ai≤ 1000,1<L<R≤1000

(2)参考代码

#include<bits/stdc++.h> 

using namespace std;
typedef long long ll;

ll i,j,k,n,m,l,r,a[100005],sb,r1,r2;
int main( )
{
cin>>n;
for(i=1;i<=n; i++){
cin>>a[i];sb+=a[i];}
cin>>l>>r;
for(i=1; i<=n;i++){
if(a[i]<l)r1+=l-a[i];
if(a[i]>r)r2+=a[i]-r;
}

if (sb<l*n||sb>r*n){
cout<<-1;}

else cout<<max(r1, r2);
return 0;
}

4. MT2029 小码哥的跳棋游戏

(1)题目描述
小码哥喜爱跳棋。跳棋游戏在一条直线上,一共n个位置( 1 ~ n ),每个位置有2个状态:0表示没有棋子,1表示有棋子。小码哥的棋子自然是能通过没有棋子的位置。当面前有1个棋子时,小码哥可以直接跳过。当有两个及以上棋子连在一起时,小码哥的棋子是跳不过去的。这时候,就要花费能量,破坏掉一些棋子,才能跳过。已知破坏一枚棋子需要花费一点能量。小码哥的棋子从第0个位置出发,现在要求小码哥到达终点(第n个位置)至少需要花费多少能量?


格式

输入格式:
第1行包含一个正整数n
第2行n个整数a ,表示棋盘的状态
.
输出格式: 一个整数,输出最小耗费的能量数

样例1:

输入
5
0 1 1 0 0
.
输出:1

(2)参考代码

#include<bits/stdc++.h> 

using namespace std;
int a[100030];
int main( )
{
int n;cin>>n;
for(int i=0;i<n;i++)
scanf("%d", &a[i]);
int tmp=0,cnt=0,res=0;
if(a[n-1]) {a[n-1]=0;res++;}
while(tmp<n){
while(tmp<n && a[tmp]){
cnt++; tmp++;
} res+=cnt/2;
cnt=0; tmp++;
} cout<<res;
return 0;
return 0;
}

5. MT2030 邮箱地址

(1)题目描述

算法竞赛入门【码蹄集进阶塔335题】(MT2026-2050)_码蹄集_03


格式

输入格式: 一行,一个字符串,表示一个地址(保证地址的字符的ASCIl在33到127间),地址长度不超过1000字符
.
输出格式: 一行,如果合法输出YES,否则输出NO

样例1

输入: 123@npu.com
.
输出: YES

(2)参考代码

#include<iostream>
#include<string>
using namespace std;
string s;
bool b(char x){//判断字符是否合法
if((x>='A'&&x<='Z')||(x>='a'&&x<='z')||(x>='0'&&x<='9')||(x=='_')){
return true;
}
return false;
}
int main(){
cin>>s;
if(b(s[0])==false){
cout<<"NO";
return 0;
}
bool flag1=true,flag2=false,flag3=false,flag_last=false;//用于判断是在 <username> , <hostname> , <resource>中的哪一部分
int tot1=0,tot2=0,tot_dit=0;//用于统计长度是否太长
if(s.find("@")==string::npos){//如果字符串里没有@,那么说明它是一定不合法的
cout<<"NO";
return 0;
}
for(int i=0;i<s.size();i++){//遍历每一个字符
if(flag1){// <username>
if(s[i]=='@'){//进入<hostname>部分
if(i==0){
cout<<"NO";
return 0;
}
flag2=true;
flag1=false;
continue;
}else{
tot1++;
if(tot1>16){//判断是否超长
cout<<"NO";
return 0;
}
if(!b(s[i])){//判断是否合法
cout<<"NO";
return 0;
}
}
}else if(flag2){//<hostname>
if(s[i]=='/'){// 进入<resource>部分
flag3=true;
flag2=false;
if(s[i-1]=='.'){//注意特判
cout<<"NO";
return 0;
}
if(s[i-1]=='/'){//注意特判
cout<<"NO";
return 0;
}
continue;
}else{
tot2++;
tot_dit++;
if(s[i]=='.'){
tot_dit=0;
if(s[i-1]=='@'){
cout<<"NO";
return 0;
}
if(s[i+1]=='.'){
cout<<"NO";
return 0;
}
if(tot2==1){//<hostname>部分 的第一个字符不能为 .
cout<<"NO";
return 0;
}
}else{
if(tot2>32){//判断是否超长
cout<<"NO";
return 0;
}
if(tot_dit>16){//判断是否超长
cout<<"NO";
return 0;
}
if(!b(s[i])){//判断是否合法
cout<<"NO";
return 0;
}
}
}
}else if(flag3){// <resource>
if(s[i-1]=='@'){
cout<<"NO";
return 0;
}
if(s[i]=='/'){
continue;
}else{
if(!b(s[i])&&s[i]!='.'){//判断是否合法
cout<<"NO";
return 0;
}
}
}
}
if(s[s.size()-1]=='/'||s[s.size()-1]=='@'||s[s.size()-1]=='.'){//注意特判字符串的末尾
cout<<"NO";
return 0;
}
cout<<"YES";
return 0;
}

6. MT2031 排队

(1)题目描述
课间休息时,男孩和女孩们在食堂里排成一队。最初孩子们站在食堂里排队。然而,过了一会儿,站在女孩们前面的男孩们开始感到尴尬,下一秒,他们会让身后的女孩站到自己前面。

让我们更精确地描述这个过程。假设队列中的位置由1到n的整数顺序编号,我们对位置号1中的人首先进行操作。如果在时间X,男孩站在第i个位置,女孩站在第i+1个位置,然后下一秒,男孩女孩的位置会交换,也就是此时第i个是女孩,第i+1个是男孩。时间是以秒为单位给出的。

你现在知道孩子们的初始位置。确定队列在T秒之后的排列方式。

格式

输入格式:
第一行包含两个整数n和t,表示队列中的人数和队列将转换成需要查找的排列的时间。
下一行输入一个字符串s,s 仅由B和G构成(B表示男孩,G表示女孩)
.
输出格式: 一个字符串,表示最后的队列

样例1

输入:
5 1
BGGBG
.
输出: GBGGB

备注:

其中: 1≤n,t ≤50

(2)参考代码

#include<bits/stdc++.h>

using namespace std;

int main( )
{
int n,t;cin>>n>>t;
string s;cin>>s;
for(int i=1;i<=t;i++){
for(int j=0;j<n-1;j++){
if(s[j]=='B'&&s[j+1]=='G'){
swap(s[j],s[j+1]);j++;
}
}
}
cout<<s;
return 0;
}

7. MT2032 建立数据库

(1)题目描述
小码哥新买了一个机器人,但是这个机器人因为很便宜只能做三个动作三个动作:

前进FD,倒退BK和重复REPEAT。
FD后加数字表示前进多少步
BK后加数字表示后退多少步
REPEAT 后加数字再加方括号,表示重复方括号里的命令。数字为正整数(保证[和数字间没有空格)

命令的格式:
1,FD与BK命令组合
2,REPEAT命令内加REPEAT命令与FD、BK组合,且REPEAT排在最后

格式

输入格式: 一行字符串(长度不超过200)
.
输出格式: 表示最后得到的步数,即离起点的距离(非负整数)

样例1

输入: REPEAT 5[ FD 50 REPEAT 10[FD 100]]
.
输出: 5250

(2)参考代码

import java.util.Scanner;
import java.util.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
int n=input.nextInt();
input.nextLine();
Map<String,Integer> map=new HashMap<String,Integer>();
for(int i=0;i<n;i++){
String s=input.nextLine();
if(map.containsKey(s)){
map.put(s,map.get(s)+1);
}else{
map.put(s,map.getOrDefault(s,0));
}
if(map.get(s)==0){
System.out.println("OK");
}else{
System.out.println(s+map.get(s).toString());
}
}

}
}

8. MT2033 碰碰车

(1)题目描述
游乐园里面大家在玩碰碰车,其中有一种碰碰车在一条直线上行驶。该碰碰车有着一个初始朝向和初始位置,并且以每秒一个单位的速度向初始方向前行,当它和其它碰碰车相遇时,它们会立刻掉头(由于速度很快,掉头时间可以忽略)。你可以算出它们在t秒后的位置吗?

格式

输入格式:
第一行有两个数字n (1- 1000) , t (0 -1000),分别表示:碰碰车的数量和所用时间。
接下来n行,每一行都有两个数字: 工,f 分别表示第n辆碰碰车的位置和方向。( 0<a ≤105,-1表示向左,1表示向右)
.
输出格式:
输出n行,每一行两个数字,分别表示碰碰车最后的位置和方向。(-1表示向左,1表示向右,0表示两车相遇)

样例1

输入:
5 2
4 1
5 -1
7 1
2 1
6 -1
.
输出:
4 0
4 0
9 1
3 -1
6 1

(2)参考代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int i,j,k,n,m,t,x[1005],v[1005];
unordered_map<int,int> cnt;
int main() {
ios::sync_with_stdio(0);
cin>>n>>t;t*=2;
for(i=1;i<=n;i++){
cin>>x[i]>>v[i];x[i]*=2;
cnt[x[i]]++;
if(cnt[x[i]]>1)return 1;
}
while(t--){
for(i=1;i<=n;i++){
cnt[x[i]]--;
x[i]+=v[i];
cnt[x[i]]++;
}
for(i=1;i<=n;i++){
if(cnt[x[i]]>1)v[i]*=-1;
}
}
for(i=1;i<=n;i++){
cout<<x[i]/2<<' '<<v[i]*(cnt[x[i]]==1)<<'\n';
}
}

9. MT2034 竖直打印机

(1)题目描述
小码哥买了一个很神奇的打印机,它能竖直地打印单词,给一个字符串,他能按单词出现的顺序竖直返回单词。

单词应该以字符串列表的形式返回,必要时用空格补位,但输出尾部的空格需要删除((不允许尾随空格)。

必要时以空格补位指的是:在竖直打印单词过程中,若出现中间的单词长度小于相邻两个单词长度,会有某行该单词没有字母的情况,这时用空格补位。

输出尾部空格的删除指的是:输出最后一行的末尾没有空格。

现要求你按照要求复制一个打印机。

格式

输入格式: 一行含空格的字符串
.
输出格式: 按列输出的字符串(以每行为字符串的形式输出)

样例1

输入: CONTEST IS COMING
.
输出:
CIC
OSO
N M
T I
E N
S G
T

备注:

1≤s.length ≤200 ,保证两个单词之间只有一个空格,且全是大写字母

(2)参考代码

import java.util.Scanner;
import java.util.*;
class Solution {
public List printVertically(String s) {
//创建list集合来存放答案
List list = new ArrayList();
//将字符串切割
String[] s1 = s.split(" ");
//创建长度用来比较
int length = Integer.MIN_VALUE;
//遍历长度来获取最大字符串长度
for (String string : s1) {
if(string.length()>length) {
length = string.length();
}
}
//遍历字符串数组
for (int i = 0; i < length; i++) {
//获取StringBuffer对象来进行字符串截切
StringBuffer sb = new StringBuffer();
for(String str : s1) {
//如果索要字符的位置超出字符串就用空格代替
if(i>=str.length()) {
sb.append(" ");
}else {//如果没有就将字符放入字符串对象中
char a = str.charAt(i);
sb.append(str.charAt(i));
}
}
//将末尾的空格处理
for(int j=sb.length()-1;j>=0;j--) {
if(sb.charAt(j)==' ') {
sb.deleteCharAt(j);
}else {
break;
}
}
//将答案放入集合中
list.add(sb.toString());
System.out.println(sb.toString());
}
return list;
}
}
class Main {
public static void main(String[] args) {
Solution sol = new Solution();
Scanner input = new Scanner(System.in);
// code here
String s = input.nextLine(); sol.printVertically(s);
input.close();
}
}

10. MT2035 伯兰语

(1)题目描述

算法竞赛入门【码蹄集进阶塔335题】(MT2026-2050)_算法_04

格式

输入格式: 输入仅一行,是你需要判断是否符合规范的单词。
.
输出格式: 输出仅一行,若符合则输出YEs,否则输出NO

样例1

输入: sumimasen
.
输出: YES

备注:

1≤输入字符串长度≤100,字符串中字符仅包含小写字母

(2)参考代码

import java.util.Scanner;
import java.util.*;

class Main {
public static void main(String[] args) {

Scanner input = new Scanner(System.in);
// code here
String s=input.nextLine();
Set<Character>set=new HashSet<>();
set.add('a');
set.add('e');
set.add('i');
set.add('o');
set.add('u');
for (int i=0;i<s.length();++i){
if (!set.contains(s.charAt(i))&&s.charAt(i)!='n'){
if (i==s.length()-1||!set.contains(s.charAt(i+1))) {
System.out.println("NO");
return;
}
}
}
System.out.println("YES");
input.close();
}
}

11. MT2036 移水造海

(1)题目描述
今天,无聊的小码哥打开了他的tr,他突发奇想,“我要把一个新世界的一块大陆用水桶运水填成海”,尽管这个点子无聊透顶,但他真的去做了。

由于小码哥使用了修改器,他拥有了无限的水桶。一个水桶的水能够刚好填上一块格子。但如果倒入水后水位高于两边中一边土地,那么水会溢出,这桶水相当于没倒过。

另外,世界左右两侧是虚空,水碰到虚空会消失

现在给了你这个世界的地形图,告诉你这个世界的宽度n以及每一列的土地的高度h,问你至少要多少水桶的水才能填满这个世界(填满即无论在哪里倒一桶水都会溢出)

格式

输入格式:
第一行一个正整数n,表示世界的宽度
第二行n个非负整数hi,表示第i列土地的高度
.
输出格式: 一个整数,表示至少需要几桶水

样例1

输入:
6
3 0 2 0 1 0
.
输出: 3

备注:

其中:3≤n ≤10000,0<h≤10000

(2)参考代码

#include <bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
typedef long long ll;
const int N = 1e6 + 7;
int a[N];
int b[N];
signed main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int h = 1; h <= 10000; h++) {
int l = 0, r = 0;
for (int i = 1; i <= n; i++) {
if (a[i] >= h) {
l = i;
break;
}
}
for (int i = n; i >= 1; i--) {
if (a[i] >= h) {
r = i;
break;
}
}
for (int i = l; i <= r; i++) {
if (a[i] < h)
b[i]++;
}
}
int ans = 0;
for (int i = 1; i <= n; i++) {
// cout << b[i] << " ";
ans += b[i];
}
// cout << endl;
cout << ans << endl;
return 0;
}

12. MT2037 奇怪的和

(1)题目描述

给出两个整数n,m,和一个n x m的矩阵。若该矩阵中两元素相同, sum(初始为零)就加上它们所在位置的曼哈顿距离。求sum的值。

格式

输入格式:
第一行为两个正整数n, m
之后的n行表示n* m的矩阵
.
输出格式: 一个数表示答案。

样例1

输入:
2 3
1 2 3
3 2 1
.
输出: 7

备注:

保证所有出现的数据均为不大于100000的正整数

(2)参考代码

#include<bits/stdc++.h>
using namespace std;

int main()
{
int n,m,num,sum=0;
multimap<int, pair<int,int>> site;
cin>>n>>m;
for(int i=0;i<n;i++){
for(int j=0;j<m;++j){
cin>>num;
site.emplace(num,make_pair(i,j));
}
}
multimap<int, pair<int,int>>:: iterator iter=site.begin();
multimap<int, pair<int,int>>:: iterator start=site.begin();

int num1,num2;
pair<int,int>index1,index2;
while(start!=site.end()){
num1=start->first;
index1=start->second;
start++;
iter=start;
num2=iter->first;
index2=iter->second;
while(num1==num2&&iter!=site.end()){
sum+=abs(index1.first-index2.first)+abs(index1.second-index2.second);
++iter;
num2=iter->first;
index2=iter->second;
}
}
cout<<sum;
return 0;
}

13. MT2038 字符矩阵

(1)题目描述
给你一个n * m的小写字符矩阵,你可以选择删除一些列,使得剩下的字符矩阵的每一行的字符串从上到下的字典序非减。即,字符串s和 t具有相等的长度,s在字典上大于t并且 s中 s和t的最大公共前缀(前缀可能为空)之后的字符按字母顺序大于t的相应字符。

求最少删除多少列

格式

输入格式: 第一行输入两个整数n, m接下来n行每行输入m个字符
.
输出格式: 输出一个整数表示最少删除的列

样例1

输入:
4 4
case
care
test
code
.
输出: 2

备注:

其中: 1≤m,n ≤100
样例解释:删除1,3列

(2)参考代码

#include <bits/stdc++.h> 
using namespace std;
const int maxn = 1e2+5;
int n,m,res;
char s[maxn][maxn];
bool temp[maxn],vis[maxn];

void copy(){
for(int i=1;i<n;i++) temp[i]=vis[i];
}

void copy2(){
for(int i=1;i<n;i++) vis[i] = temp[i];
}

int main()
{
cin >> n >> m;
for(int i=1;i<=n;i++){
cin>>s[i]+1;
}
for(int j=1;j<=m;j++){
copy();
for(int i=1;i<n;i++){
if(!temp[i]&& s[i][j] > s[i+1][j]){
res++;
break;
}else if(s[i][j] < s[i+1][j]){
temp[i] = 1;
}
if(i==n-1) copy2();
}
}
cout<<res<<endl;
return 0;
}

14. MT2039 换换换

(1)题目描述
机器人小R在看一个魔术表演,魔术师面前有一排共N个倒扣着的杯子,其中每一个下面都有一个小玩具 t,并且每个小玩具都是唯一的。魔术师飞快地变换杯子之后让小R猜其中M个玩具 t,在哪个杯子里。由于机器人小R内置的程序只能记录杯子的数量N,小玩具初始的位置p ,以及魔术师每次变换杯子的位置P1,p2。小R的主人希望你能写一个程序,帮助小R找出玩具。

格式

输入格式:
第一行给定三个整数N ,M ,T,T为魔术师操作的次数
接下来的Ⅳ行,每行给定一个字符串 ti;
之后的T行,每行给定两个位置 p1,p2,位置从1开始计数最后M 行,每行给定一个字符串t ,。
.
输出格式: M 行,每行一个整数,表示杯子现在的序号

样例1

输入:
5 5 5
car
van
track
dog
cat
1 2
4 5
3 2
5 1
1 4
van
car
track
dog
cat
.
输出:
5
3
2
4
1

备注:

其中:100≤N, M , T ≤5e4,1 ≤ti/≤20, t,∈ { ti }

(2)参考代码

def main():
#code here
n,q,t = map(int,input().split())
s2idx = {}
arr = [""]
for i in range(1,n+1):
s = input()
arr.append(s)
s2idx[s] =i
for _ in range(t):
a,b = map(int,input().split())
sa,sb = arr[a],arr[b]
idxa,idxb = s2idx[sa],s2idx[sb]
s2idx[sa] = idxb
s2idx[sb] = idxa
arr[a],arr[b] = arr[b],arr[a]
for _ in range(q):
s = input()
print(s2idx[s])


if __name__ == '__main__':
main();

15. MT2040 银行账户

(1)题目描述

据说对银行账户进行盗窃时,如果只盗取小数点下的数值,就不容易引起注意,所以你决定进行尝试

银行总共有n个账户,m次转账,对每次转账,你可以盗取(转账金额-转账金额下取整)的资金,并使转入账户的警戒值增加相同数值,当任意账户的警戒值>1,或者无法实现转账(转出账户余额不足),或者m 次转账全部完成,你停止盗取,请计算总盗取金额

格式

输入格式:
第一行n,m,表示有n个账户,m条转账记录
第二行n个实数,表示每个账户的资金
接下来m行,每行有三个参数
整数a,整数y,实数z,分别表示转出账户,转入账户,和转账金额
.
输出格式: 输出盗取金额,保留两位小数

样例1

输入:
5 5
2 2 2 2 2
1 2 1.5
2 1 1.5
1 2 1.5
2 1 1.5
1 2 1.5
.
输出: 2.00

(2)参考代码

def main():
#code here
n,m=[int(x) for x in input().split()]
money=[0.0]+[float(x) for x in input().split()]
lim=[1]*(n+1)
sm=0.0
for iterator in range(m):
line = input().split()
x,y,z=int(line[0]),int(line[1]),float(line[2])

if money[x]-z<-0.00000001:
break

gap=z-int(z)
sm+=gap;
lim[y]-=gap;
if lim[y]<-0.00000001:
break
money[x] -= z;
money[y] += z-gap;
print("%.2lf"%(sm))


if __name__ == '__main__':
main();

16. MT2041 三角形的个数

(1)题目描述
最近璃月的海灯节到了,一位来自码蹄集的小码哥正好游历至此,一种有趣的装饰图案引起了他的兴趣:这种图案将一个三角形每条边分为n等分,然后将对应的等分点相连,使得连成的线段平行于三条边中的一条,这样就构成了大三角套小三角的繁复图案。现在有许多类似的图案,这名学者想知道每个图案中各包含了几个三角形,请你帮帮他。

如图所示是一个二等分的例子:

算法竞赛入门【码蹄集进阶塔335题】(MT2026-2050)_码蹄集_05

格式

输入格式:
第一行一个正整数N,代表图案个数。
接下来N行每行一个正整数n,代表第i个三角形每条边被分为了n等分
.
输出格式: 输出NⅣ行,每行一个正整数代表第i个图案中包含的三角形个数

样例1

输入:
2
2
3
.
输出:
5
13

备注:

1≤N ≤100。
1≤n ≤500。
最大的三角形别忘了算哦!

(2)参考代码

#include<bits/stdc++.h> 
/*N =((n + 1)(2n^2 + 3n - 1) / 8),n为奇数;

N = (n(n + 2)(2n + 1) / 8),n为偶数;*/
using namespace std;

int main( )
{int n,a[100+10],b[100+10];
cin >> n ;
for(int i=0;i<n;i++){
cin >> a[i];
int sum=0;
if(a[i]%2==0)//偶数等分
sum= a[i]*(a[i]+2)*(2*a[i]+1)/8;
else
sum =(a[i]+1)*(2*a[i]*a[i]+3*a[i]-1)/8;
b[i]=sum;
}
for(int i=0;i<n;i++)
cout<<b[i]<<endl;

return 0;
}

17. MT2042 硬币塔

(1)题目描述
一个k级的硬币塔从下到上,由1个银币,一个k-1级硬币塔,k个金币,一个k―1级硬币塔,1个银币堆成。其中,0级硬币塔只有一个金币。

问:n级硬币塔从下向上数i个有几个金币。

格式

输入格式: 一行用空格隔开的两个整数n, i
.
输出格式: 一个整数表示答案

样例1

输入: 5 13
.
输出: 6

备注:

数据范围:0≤n≤40

(2)参考代码

#include<stdio.h>
long long int counthang(int n)
{
if(n==0)
return 1;
else
return 2+n+2*counthang(n-1);
}
long long int count(int n)
{
if(n==0)
return 1;
else
return n+2*count(n-1);
}
void jilu(int n,long long int i,long long int *sum)
{
if(n == 0){
if( i > 0)
*sum += 1;
return;
}
long long int num=counthang(n);
long long int temp = counthang( n - 1);
if( i <= n){
*sum+=0;
}else if(i>=num-n)// 1 | k-1 | k | k-1 | 1
{
*sum+=count(n);
}
else if( i > (temp + n + 1) )
{
*sum+=count(n-1)+ n;
jilu(n-1,i-temp-n - 1,sum);
}
else if(i> temp + 1)
{
*sum+= count(n-1)+i - temp -1;
}
else if ( i > n)
{
jilu(n-1,i-1,sum);
}
}
int main()
{
long long int i,sum=0;
int n;
scanf("%d %lld",&n,&i);
jilu(n,i,&sum);
printf("%lld",sum);
return 0;
}

18. MT2043 数字问题

(1)题目描述
输入n,输出1―n的自然数中各数位只包含0或1的数的个数。

格式

输入格式: 输入一个整型数字n(1 ≤n ≤ 1e9)
.
输出格式: 输出一行一个整数表示答案

样例1

输入: 19
.
输出: 3

(2)参考代码

#include<bits/stdc++.h>
using namespace std;

long long ans, n;

void solve(long long x)
{
if(x > n) return ;
ans ++;
solve( x * 10);
solve( x * 10 + 1);
}

int main()
{
scanf("%lld",&n);
solve(1);
printf("%lld\n",ans);
return 0;
}

19. MT2044 字符串的解码

(1)题目描述

算法竞赛入门【码蹄集进阶塔335题】(MT2026-2050)_数据结构_06

格式

输入格式: 一行字符串
.
输出格式: 一行字符串

样例1

输入: AC[3FUN]
.
输出: ACFUNFUNFUN

备注:

解码后的字符串长度在50000以内,最多只有十重方括号。保证只含数字、大写字母和方括号

(2)参考代码

def main():
s = input()
n = len(s)
arr = []
mm = {}
for i in range(n):
if s[i] == '[':
arr.append(i)
elif s[i] == ']':
mm[arr[-1]] = i
arr.pop(-1)

def decode(ii, jj):
if ii > jj:
return ""
if ii == jj:
return s[ii]

if s[ii] == '[':
x = ii + 1
while x + 1 < jj and '0' <= s[x + 1] <= '9':
x += 1

k = int(s[ii + 1: x + 1])
return decode(x + 1, mm[ii] - 1) * k + decode(mm[ii] + 1, jj)

else:
x = ii
while x + 1 <= jj and s[x + 1] not in "[]":
x += 1

return s[ii: x + 1] + decode(x + 1, jj)

print(decode(0, n - 1))


if __name__ == '__main__':
main();

20. MT2045 河内双塔

(1)题目描述

算法竞赛入门【码蹄集进阶塔335题】(MT2026-2050)_开发语言_07

格式

输入格式: 输入一个正整数n,表示在A柱上放有2n 个圆盘。
.
输出格式: 输出一个正整数,为完成上述任务所需的最少移动次数。

样例1

输入: 1
.
输出: 2

备注:

提示: 1≤n ≤50

(2)参考代码

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
#define ll long long
#define N 10000
ll a[N] ;
int main(){
ll n;
cin >> n;
a[1] = 1 ;
for (ll i = 2; i <= n; i++){
a[i] = a[i - 1] * 2 + 1 ;
}
cout << a[n] * 2 ;
return 0;
}

21. MT2046 斐波那契,但是是字符串

(1)题目描述

算法竞赛入门【码蹄集进阶塔335题】(MT2026-2050)_c++_08

格式

输入格式: 两个整数n,c意义如题
.
输出格式: 一个字符表示答案

样例1

输入: 5 6
.
输出: I

备注:

数据范围:0≤n ≤80,1 ≤c≤第n项字符串的长度

(2)参考代码

#include<bits/stdc++.h>

using namespace std;

string a0 = "IAKIOI";
string a1 = "WHENWILLSCORLLOFTAIWUCOMEOUT!!!";
//保存字符串数组
vector<string> ss={a0,a1};
vector<unsigned long long> len_arr;

//递推查找
char search(long long n, long long c){
while(1){
if(n==0 || n==1){
return ss[n][c-1];
}
long long len1 = len_arr[n-2];
long long len2 = len_arr[n-1];
if(c>len1){
n=n-1;
c=c-len1;
}else{
n=n-2;
}
}
}

int main( )
{
int n=0;
long long c=0;
//读取输入信息
cin>>n>>c;

//初始化信息
len_arr.push_back(a0.length());
len_arr.push_back(a1.length());

//获取第n项字符串的长度
for(int i=2;i<=n;i++){

len_arr.push_back(len_arr[len_arr.size()-1]+len_arr[len_arr.size()-2])
;
}

printf("%c",search(n,c));
return 0;
}

22. MT2047 巨大的错误

(1)题目描述
提瓦特大陆上有一个贫穷的占星术士小码哥,在占星的时候,小码哥时常需要将命运启示他的信息与手中命运之轮上的命星一一对应,现在有n个启示和n个命星需要一一对应,有时,因为命运实在太过难以言明,小码哥会将所有的启示与命星都对应错了,此时称小码哥犯了一个巨大的错误,问一共有多少种情况可被称为“巨大的错误”。

格式

输入格式: 输入一个正整数n
.
输出格式: 输出一个正整数代表所求答案

样例1

输入: 2
.
输出: 1

备注:

其中: n≤20。

(2)参考代码

#include<iostream>
using namespace std;
long long f[25],n;
int main()
{
cin>>n;
f[1]=0;f[2]=1;f[3]=2;
if(n==1||n==2||n==3){
cout<<f[n];
return 0;
}
for(long long i=4;i<=n;i++)f[i]=(i-1)*(f[i-1]+f[i-2]);
cout<<f[n];
return 0;
}

23. MT2048 距离平方和

(1)题目描述
你有n个点,请编写一个程序,求这n个点的距离的平方和。

格式

输入格式:
第一行:一个整数n (0≤n ≤100000) ;
接下来n行:每行两个整数c,g,表示该点坐标(-10000≤,g ≤10000)。
.
输出格式: 仅一行:所有点的距离的平方和。

样例1

输入:
4
1 1
-1 -1
1 -1
-1 1
.
输出: 32

(2)参考代码

#include<bits/stdc++.h> 

using namespace std;

int main( )
{
int n;
cin>>n;
long long int x=0,y=0;
long long int dx=0,dy=0,dis=0;
for(int i=0;i<n;i++){
cin>>x>>y;
dis+=pow(x,2)+pow(y,2);
dx+=x;
dy+=y;
}
dis = dis*n-dx*dx-dy*dy;
cout<<dis;
return 0;
}

24. MT2049 三连

(1)题目描述
给出一个长度为n的序列,问有多少种方案将序列划分为恰好连续的三段(每个元素都属于某一段),使得每一段的和都相等。

格式

输入格式:
第一行:—个整数n
第二行: n个整数,表示序列
.
输出格式: 一个整数表示方案数

样例1

输入:
4
1 2 3 3
.
输出: 1

备注:

其中: 1≤n ≤le5,|序列中的每个数|≤10000

(2)参考代码

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN=1e5+5;
typedef long long ll;
ll pre[MAXN];

ll ans,cnt;

int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",pre+i);
pre[i]+=pre[i-1];
}
if(pre[n]%3)
{
printf("0");
return 0;
}
ll wz=pre[n]/3;
for(int i=1;i<n;i++)
{
if(pre[i]==wz<<1) ans+=cnt;
if(pre[i]==wz) cnt++;
}
printf("%lld",ans);
return 0;
}

25. MT2050 运动会进行中

(1)题目描述
运动会快到了,小码哥班里组织彩排,小码哥作为体委不得不担当同学排队列的大任。

为了让男女分配均匀,小码哥想知道队列中男女生人数一样的子序列(连续的)最多多长。

格式

输入格式:
第一行有一个正整数n,代表学校的人数。n ≤100000
第二行有n个用空格隔开的数,这些数只能是О或1,其中,0代表一个女生,1代表一个男生
.
输出格式:
输出一个非负整数。这个数表示在输入数据中最长的一段男女人数相等的子序列长度。
如果不存在男女人数相等的子序列,请输出0。

样例1

输入:
9
0 1 0 0 0 1 1 0 0
.
输出: 6

(2)参考代码

#include<bits/stdc++.h> 

using namespace std;

class seq{
public:
int min_no = -1;
int max_no = -1;
};


int main( )
{
int n,a[100005]={0};
map<int,seq> record;
cin>>n;
int sum_all = 0;
for(int i=1;i<=n;i++){
cin>>a[i];
a[i] = a[i] ==0?-1:1;
sum_all+=a[i];
if(record[sum_all].min_no==-1) record[sum_all].min_no=i;
else record[sum_all].max_no = i;
}
int result=0;
for(auto i:record) result = max(result,i.second.max_no-i.second.min_no);
cout<<result;
return 0;
}

结语

感谢大家一直以来的不断支持与鼓励,​​码题集​​题库中的进阶塔350题正在逐步更新,之后会逐步跟进星耀,王者的题,尽请期待!!!
同时,也希望这些题能帮助到大家,一起进步,祝愿每一个算法道路上的“苦行僧”们,都能够历经磨难,终成正果,既然选择了这条路,走到了这里,中途放弃,岂不是太过可惜?

另附中国计算机学会的杰出会员、常务理事轩哥博士的B站视频讲解链接​​https://space.bilibili.com/518554541/?spm_id_from=333.999.0.0​​,供大家更好的进行学习与刷题~( ̄▽ ̄~)~

愿你的结局,配得上你一路的颠沛流离。