CSDN编程竞赛:第33期题目详解和源代码实现 2023.3.1

Posted 禅与计算机程序设计艺术

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CSDN编程竞赛:第33期题目详解和源代码实现 2023.3.1相关的知识,希望对你有一定的参考价值。

目录

1.给定一个存放整数的数组,重新排列数组使得数组左边为奇数,右边为偶数; 数字保持原来的顺序。

2.已知字符串s,添加多少字符可以使得s变成回文串。

3.选择客栈

4.公司新表


1.给定一个存放整数的数组,重新排列数组使得数组左边为奇数,右边为偶数; 数字保持原来的顺序。


    public static ArrayList<Integer> solution(int n, ArrayList<Integer> arr) 
        ArrayList<Integer> odd = new ArrayList<Integer>();
        ArrayList<Integer> even = new ArrayList<Integer>();
        for (int i = 0; i < arr.size(); i++) 
            if (arr.get(i) % 2 == 0) 
                even.add(arr.get(i));
             else 
                odd.add(arr.get(i));
            
        
        odd.addAll(even);
        return odd;
    

2.已知字符串s,添加多少字符可以使得s变成回文串。


//    用Java语言实现:已知字符串s,添加多少字符可以使得s变成回文串。
//    输入:字符串s
//    输出:最少需要添加字符的数量。

    public static int solution(String s)
        int count = 0;
        int n = s.length();

        int[][] dp = new int[n][n];
        // dp[i][j] 表示 s[i..j] 这个子串变成回文串需要最少添加的字符数

        // 从最小的字串开始构造
        for (int i = 0; i < n; i++) 
            for (int j = i; j >= 0; j--) 
                if (i == j) 
                    dp[j][i] = 0;
                 else if (i == j + 1) 
                    dp[j][i] = s.charAt(i) == s.charAt(j) ? 0 : 1;
                 else 
                    if (s.charAt(i) == s.charAt(j)) 
                        dp[j][i] = dp[j + 1][i - 1];
                     else 
                        dp[j][i] = 1 + Math.min(dp[j + 1][i], dp[j][i - 1]);
                    
                
            
        
        count = dp[0][n - 1];
        return count;
    


 

3.选择客栈


丽江河边有 n 家很有特色的客栈,客栈按照其位置顺序从 1 到 n 编号。每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖啡店均有各自的最低消费。 两位游客一起去丽江旅游,他们喜欢相同的色调,又想尝试两个不同的客栈,因此决定分别住在色调相同的两家客栈中。晚上,他们打算选择一家咖啡店喝咖啡,要求咖啡店位于两人住的两家客栈之间(包括他们住的客栈),且咖啡店的最低消费不超过 p 。 他们想知道总共有多少种选择住宿的方案,保证晚上可以找到一家最低消费不超过 p 元的咖啡店小聚。

第一行三个整数 n, k, p,用空格隔开,分别表示客栈的个数,色调的数目和能接受的最低消费的最高值;

接下来的 n 行,每行两个整数,空格隔开,分别表示客栈的装饰色调和咖啡店的最低消费。

n, k, p = map(int, input().strip().split())
inn = []
for i in range(n):
    inn.append(list(map(int, input().strip().split())))
 
res = 0
dp = [[0]*2 for _ in range(k)] # 步骤1
for i in range(n):
    res += dp[inn[i][0]][0] if inn[i][1] <= p else dp[inn[i][0]][1] # 步骤2
    dp[inn[i][0]][0] += 1 # 步骤3
    if inn[i][1] <= p: # 步骤4
        for j in range(k): # 步骤5
            dp[j][1] = dp[j][0]
print(res)

4.公司新表


题目描述
公司里为了凸显公司的特性。
安装了一个n进制表。
已知新的表的时间是”H:M”。
时间合法的定义为H<=23 && M<=59。
时间有多少种进制定义的方式,依次打印出来。
如果有无数种解输出”-1”,不存在输出”0”。

输入描述:

输入一行字符串a:b形式。

输出描述:

输出答案。

输入样例:

11:20

输出样例:

3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

分析
这题题目描述不够清楚,但是有用例解释还是可以理解的,给定一个字符串,如果用k进制解释这个字符串后的数字大小在时钟范围内,就是合法的。简单的模拟题,由于比赛时状态不佳,只通过了六成用例,赛后重新写了下。

首先要考虑的是字符串的解析,尽管题目用例给的是像11 : 20 11:2011:20之类的字符串,但是是否存在1 : 2 1:21:2,甚至是122 : 234 122:234122:234类似的字符串,也不能保证。字符串中出现的最大字符转化为数字后是t,那么至少要t + 1进制才能表示该字符串。

如果字符串是用i ii进制表示的,将冒号前后的字符串转化为十进制数字后得到x : y x:yx:y,只要x < 24 , y < 60 x<24,y<60x<24,y<60,那么这个进制表示就是合法的。注意如果使用i ii进制表示是合法的,那么使用i − 1 i-1i−1进制表示的数值只会更小,也是合法的。像01 : 01 01:0101:01这类只有一位的表示,不管是几进制表示得到的数都很小,因为最低位的基数都是1。我们可以从t + 1 t + 1t+1枚举到60,如果60进制都是合法的,更高进制的表示一定也是合法的,因为如果时间有两位表示,60进制的两位数是不小于60的。60进制合法就表示有无数种解。
 

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int get(char c) 
	if (c >= '0' && c <= '9')	return c - '0';
	else	return c - 'A' + 10;

std::vector<int> solution(std::string m) 
	std::vector<int> res;
	int t = 0;
	int n = m.size();
	for(int i = 0; i < n; i++) 
		if(m[i] == ':') continue;
		t = max(t, get(m[i]));
	
	for(int i = t + 1; i <= 60; i++) 
		int b[2] = 0, 0;
		int p = 0;
		for(int j = 0;j < n;j++) 
			if(m[j] == ':') 
				p++;
				continue;
			
			int q = get(m[j]);
			b[p] = b[p] * i + q;
		
		if(b[0] >= 24 || b[1] >= 60) break;
		else res.push_back(i);
	
	if (!res.size()) 
		return 0;
	 else if(res.back() == 60) return -1;
	return res;

int main() 
	std::string m;
	getline(std::cin, m);;
	std::vector<int> result = solution(m);
	for(auto it=result.begin(); it!=result.end(); ++it) 
		std::cout<<*it<<" ";
	
	std::cout<<std::endl;
	return 0;

以上是关于CSDN编程竞赛:第33期题目详解和源代码实现 2023.3.1的主要内容,如果未能解决你的问题,请参考以下文章

CSDN编程竞赛 ——— 第六期

CSDN编程竞赛 ——— 第六期

CSDN竞赛第33期题解

CSDN竞赛第33期题解

CSDN编程竞赛 ——— 第二十一期

CSDN编程竞赛 ——— 第二十一期