更多文章:TT的博客
1. 数据分类处理
描述
信息社会,有海量的数据需要分析处理,比如公安局分析身份证号码、 QQ 用户、手机号码、银行帐号等信息及活动记录。
采集输入大数据和分类规则,通过大数据分类处理程序,将大数据分类输出。
数据范围:1 ≤ I,R ≤ 100 ,输入的整数大小满足 0 ≤ val ≤ 231−1
输入描述:
一组输入整数序列I和一组规则整数序列R,I和R序列的第一个整数为序列的个数(个数不包含第一个整数);整数范围为0~(2^31)-1,序列个数不限。
输出描述:
从R依次中取出Ri,对I进行处理,找到满足条件的I:
I整数对应的数字需要连续包含Ri对应的数字。比如Ri为23,I为231,那么I包含了Ri,条件满足 。
按Ri从小到大的顺序:
(1)先输出Ri;
(2)再输出满足条件的I的个数;
(3)然后输出满足条件的I在I序列中的位置索引(从0开始);
(4)最后再输出I。
附加条件:
(1)Ri需要从小到大排序。相同的Ri只需要输出索引小的以及满足条件的I,索引大的需要过滤掉
(2)如果没有满足条件的I,对应的Ri不用输出
(3)最后需要在输出序列的第一个整数位置记录后续整数序列的个数(不包含“个数”本身)
序列I:15,123,456,786,453,46,7,5,3,665,453456,745,456,786,453,123(第一个15表明后续有15个整数)
序列R:5,6,3,6,3,0(第一个5表明后续有5个整数)
输出:30, 3,6,0,123,3,453,7,3,9,453456,13,453,14,123,6,7,1,456,2,786,4,46,8,665,9,453456,11,456,12,786
说明:
30----后续有30个整数
3----从小到大排序,第一个Ri为0,但没有满足条件的I,不输出0,而下一个Ri是3
6— 存在6个包含3的I
0— 123所在的原序号为0
123— 123包含3,满足条件
示例
输入:
15 123 456 786 453 46 7 5 3 665 453456 745 456 786 453 123
5 6 3 6 3 0
输出:
30 3 6 0 123 3 453 7 3 9 453456 13 453 14 123 6 7 1 456 2 786 4 46 8 665 9 453456 11 456 12 786
说明:
将序列R:5,6,3,6,3,0(第一个5表明后续有5个整数)排序去重后,可得0,3,6。
序列I没有包含0的元素。
序列I中包含3的元素有:I[0]的值为123、I[3]的值为453、I[7]的值为3、I[9]的值为453456、I[13]的值为453、I[14]的值为123。
序列I中包含6的元素有:I[1]的值为456、I[2]的值为786、I[4]的值为46、I[8]的值为665、I[9]的值为453456、I[11]的值为456、I[12]的值为786。
最后按题目要求的格式进行输出即可。
题解
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
int Inum = in.nextInt();
String[] arrI = new String[Inum];
for (int i = 0; i < Inum; i++) {
arrI[i] = String.valueOf(in.nextInt());
}
int Rnum = in.nextInt();
Map<Integer, Integer> mapR = new TreeMap<>();
for (int i = 0; i < Rnum; i++) {
mapR.put(in.nextInt(), 0);
}
List<String> list = new ArrayList<>();
int num = 0;
for (int i : mapR.keySet()) {
for (int j = 0; j < Inum; j++) {
if (arrI[j].contains(String.valueOf(i))) {
mapR.put(i, mapR.get(i) + 1);
list.add(String.valueOf(j));
list.add(arrI[j]);
num += 2;
}
}
if (mapR.get(i) != 0) {
num += 2;
}
}
System.out.print(num + " ");
int x = 0;
for (int i : mapR.keySet()) {
if (mapR.get(i) != 0) {
System.out.print(i + " " + mapR.get(i) + " ");
for (int j = x; j < (2 * mapR.get(i)) + x; j++) {
System.out.print(list.get(j) + " ");
}
x += 2 * mapR.get(i);
}
}
}
}
}
2. 字符串排序
描述
编写一个程序,将输入字符串中的字符按如下规则排序。
规则 1 :英文字母从 A 到 Z 排列,不区分大小写。
如,输入: Type 输出: epTy
规则 2 :同一个英文字母的大小写同时存在时,按照输入顺序排列。
如,输入: BabA 输出: aABb
规则 3 :非英文字母的其它字符保持原来的位置。
如,输入: By?e 输出: Be?y
数据范围:输入的字符串长度满足 1 ≤ n ≤ 1000
输入描述:
输入字符串
输出描述:
输出字符串
示例
输入:A Famous Saying: Much Ado About Nothing (2012/8)
输出:A aaAAbc dFgghh: iimM nNn oooos Sttuuuy (2012/8).
题解
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
char[] cs = in.nextLine().toCharArray();
List<Character> list = new ArrayList<>();
for (char c : cs) {
if (Character.isLetter(c)) {
list.add(c);
}
}
Collections.sort(list, (o1, o2) -> {
Character c = Character.toLowerCase(o1);
return c.compareTo((Character.toLowerCase(o2)));
});
int n = 0;
for (char c : cs) {
if (Character.isLetter(c)) {
System.out.print(list.get(n));
n++;
} else {
System.out.print(c);
}
}
}
}
}
3. 查找兄弟单词
描述
定义一个单词的“兄弟单词”为:交换该单词字母顺序(注:可以交换任意次),而不添加、删除、修改原有的字母就能生成的单词。
兄弟单词要求和原来的单词不同。例如: ab 和 ba 是兄弟单词。 ab 和 ab 则不是兄弟单词。
现在给定你 n 个单词,另外再给你一个单词 x ,让你寻找 x 的兄弟单词里,按字典序排列后的第 k 个单词是什么?
注意:字典中可能有重复单词。
数据范围: 1 ≤ n ≤ 1000,输入的字符串长度满足 1 ≤ len(str) ≤ 10,1 ≤ k ≤ n
输入描述:
输入只有一行。 先输入字典中单词的个数n,再输入n个单词作为字典单词。 然后输入一个单词x 最后后输入一个整数k
输出描述:
第一行输出查找到x的兄弟单词的个数m 第二行输出查找到的按照字典顺序排序后的第k个兄弟单词,没有符合第k个的话则不用输出。
示例
输入:
6 cab ad abcd cba abc bca abc 1
输出:
3
bca
说明:abc的兄弟单词有cab cba bca,所以输出3,经字典序排列后,变为bca cab cba,所以第1个字典序兄弟单词为bca
题解
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
String[] ss = in.nextLine().split(" ");
int n = Integer.parseInt(ss[0]);
String s = ss[ss.length - 2];
int num = Integer.parseInt(ss[ss.length - 1]);
List<String> list = new ArrayList<>();
for(int i = 1; i <= n; i++){
if(ss[i].length() != s.length() || ss[i].equals(s)){
continue;
}
char[] chars = s.toCharArray();
char[] charx = ss[i].toCharArray();
Arrays.sort(chars);
Arrays.sort(charx);
if(new String(chars).equals(new String(charx))){
list.add(ss[i]);
}
}
Collections.sort(list);
System.out.println(list.size());
if(list.size() > num){
System.out.println(list.get(num - 1));
}
}
}
}
4. 素数伴侣
描述
若两个正整数的和为素数,则这两个正整数称之为“素数伴侣”,如2和5、6和13,它们能应用于通信加密。现在密码学会请你设计一个程序,从已有的 N ( N 为偶数)个正整数中挑选出若干对组成“素数伴侣”,挑选方案多种多样,例如有4个正整数:2,5,6,13,如果将5和6分为一组中只能得到一组“素数伴侣”,而将2和5、6和13编组将得到两组“素数伴侣”,能组成“素数伴侣”最多的方案称为“最佳方案”,当然密码学会希望你寻找出“最佳方案”。
输入:
有一个正偶数 n ,表示待挑选的自然数的个数。后面给出 n 个具体的数字。
输出:
输出一个整数 K ,表示你求得的“最佳方案”组成“素数伴侣”的对数。
数据范围:2 ≤ val ≤ 30000
输入描述:
输入说明
1 输入一个正偶数 n
2 输入 n 个整数
输出描述:
求得的“最佳方案”组成“素数伴侣”的对数。
示例
输入:
4
2 5 6 13
输出:
2
题解
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
int n = sc.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
}
ArrayList<Integer> evens = new ArrayList();
ArrayList<Integer> adds = new ArrayList();
for (int i = 0; i < n; i++) {
if ((arr[i] & 1) == 1) {
evens.add(arr[i]);
} else {
adds.add(arr[i]);
}
}
int[] evensMatch = new int[evens.size()];
int count = 0;
for (int i = 0; i < adds.size(); i++) {
int[] used = new int[evens.size()];
if (find(used, evens, adds.get(i), evensMatch))
count++;
}
System.out.println(count);
}
}
public static boolean isPrime(int m) {
for (int i = 2; i * i <= m; i++) {
if (m % i == 0) {
return false;
}
}
return true;
}
public static boolean find(int[] used, ArrayList<Integer> evens, int num,
int[] evensMatch) {
for (int i = 0; i < evens.size(); i++) {
if (isPrime(num + evens.get(i)) && used[i] == 0) {
used[i] = 1;
if (evensMatch[i] == 0 || find(used, evens, evensMatch[i], evensMatch)) {
evensMatch[i] = num;
return true;
}
}
}
return false;
}
}
5. 字符串加解密
描述
对输入的字符串进行加解密,并输出。
加密方法为:
当内容是英文字母时则用该英文字母的后一个字母替换,同时字母变换大小写,如字母a时则替换为B;字母Z时则替换为a;
当内容是数字时则把该数字加1,如0替换1,1替换2,9替换0;
其他字符不做变化。
解密方法为加密的逆过程。
数据范围:输入的两个字符串长度满足 1 ≤ n ≤ 1000 ,保证输入的字符串都是只由大小写字母或者数字组成
输入描述:
第一行输入一串要加密的密码
第二行输入一串加过密的密码
输出描述:
第一行输出加密后的字符
第二行输出解密后的字符
示例
输入:
abcdefg
BCDEFGH
输出:
BCDEFGH
abcdefg
题解
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
char[] char1 = in.nextLine().toCharArray();
char[] char2 = in.nextLine().toCharArray();
for(int i = 0; i < char1.length; i++){
if(char1[i] >= 'A' && char1[i] <= 'Y'){
System.out.print((char)(char1[i] + 33));
}else if (char1[i] == 'Z'){
System.out.print('a');
}else if(char1[i] >= 'a' && char1[i] <= 'y'){
System.out.print((char)(char1[i] - 31));
}else if (char1[i] == 'z'){
System.out.print('A');
}else if (char1[i] >= '0' && char1[i] < '9'){
System.out.print((char)(char1[i] + 1));
}else if (char1[i] == '9'){
System.out.print('0');
}else{
System.out.print(char1[i]);
}
}
System.out.println();
for(int i = 0; i < char2.length; i++){
if(char2[i] >= 'B' && char2[i] <= 'Z'){
System.out.print((char)(char2[i] + 31));
}else if (char2[i] == 'A'){
System.out.print('z');
}else if(char2[i] >= 'b' && char2[i] <= 'z'){
System.out.print((char)(char2[i] - 33));
}else if (char2[i] == 'a'){
System.out.print('Z');
}else if (char2[i] > '0' && char2[i] <= '9'){
System.out.print((char)(char2[i] - 1));
}else if (char2[i] == '0'){
System.out.print('9');
}else{
System.out.print(char2[i]);
}
}
System.out.println();
}
}
}
6. 字符串合并处理
描述
按照指定规则对输入的字符串进行处理。
详细描述:
第一步:将输入的两个字符串str1和str2进行前后合并。如给定字符串 “dec” 和字符串 “fab” , 合并后生成的字符串为 “decfab”
第二步:对合并后的字符串进行排序,要求为:下标为奇数的字符和下标为偶数的字符分别从小到大排序。这里的下标的意思是字符在字符串中的位置。注意排序后在新串中仍需要保持原来的奇偶性。例如刚刚得到的字符串“decfab”,分别对下标为偶数的字符’d’、‘c’、‘a’和下标为奇数的字符’e’、‘f’、'b’进行排序(生成 ‘a’、‘c’、‘d’ 和 ‘b’ 、‘e’ 、‘f’),再依次分别放回原串中的偶数位和奇数位,新字符串变为“abcedf”
第三步:对排序后的字符串中的’0’‘9’、‘A’‘F’和’a’~'f’字符,需要进行转换操作。
转换规则如下:
对以上需要进行转换的字符所代表的十六进制用二进制表示并倒序,然后再转换成对应的十六进制大写字符(注:字符 a~f 的十六进制对应十进制的10~15,大写同理)。
如字符 ‘4’,其二进制为 0100 ,则翻转后为 0010 ,也就是 2 。转换后的字符为 ‘2’。
如字符 ‘7’,其二进制为 0111 ,则翻转后为 1110 ,对应的十进制是14,转换为十六进制的大写字母为 ‘E’。
如字符 ‘C’,代表的十进制是 12 ,其二进制为 1100 ,则翻转后为 0011,也就是3。转换后的字符是 ‘3’。
根据这个转换规则,由第二步生成的字符串 “abcedf” 转换后会生成字符串 “5D37BF”。
数据范围:输入的字符串长度满足 1 ≤ n ≤ 100
输入描述:
样例输入两个字符串,用空格隔开。
输出描述:
输出转化后的结果。
示例
输入:ab CD
输出:3B5D
说明:合并后为abCD,按奇数位和偶数位排序后是CDab(请注意要按ascii码进行排序,所以C在a前面,D在b前面),转换后为3B5D
题解
import java.util.*;
public class Main {
public static void main(String[] args) {
Map<Character, Character> map = new HashMap<Character, Character>() {
{
put('0', '0');
put('1', '8');
put('2', '4');
put('3', 'C');
put('4', '2');
put('5', 'A');
put('6', '6');
put('7', 'E');
put('8', '1');
put('9', '9');
put('a', '5');
put('b', 'D');
put('c', '3');
put('d', 'B');
put('e', '7');
put('f', 'F');
put('A', '5');
put('B', 'D');
put('C', '3');
put('D', 'B');
put('E', '7');
put('F', 'F');
}
};
Scanner in = new Scanner(System.in);
while (in.hasNextLine()) {
char[] cs = in.nextLine().replace(" ", "").toCharArray();
List<Character> list1 = new ArrayList<>();
List<Character> list2 = new ArrayList<>();
for (int i = 0; i < cs.length; i++) {
if (i % 2 == 0) {
list1.add(cs[i]);
} else {
list2.add(cs[i]);
}
}
Collections.sort(list1);
Collections.sort(list2);
Iterator<Character> iterator1 = list1.iterator();
Iterator<Character> iterator2 = list2.iterator();
for (int i = 0; i < cs.length; i++) {
if (i % 2 == 0) {
char c = iterator1.next();
if (map.containsKey(c)) {
System.out.print(map.get(c));
} else {
System.out.print(c);
}
} else {
char c = iterator2.next();
if (map.containsKey(c)) {
System.out.print(map.get(c));
} else {
System.out.print(c);
}
}
}
}
}
}
7. 单词倒排
描述
对字符串中的所有单词进行倒排。
说明:
1、构成单词的字符只有26个大写或小写英文字母;
2、非构成单词的字符均视为单词间隔符;
3、要求倒排后的单词间隔符以一个空格表示;如果原字符串中相邻单词间有多个间隔符时,倒排转换后也只允许出现一个空格间隔符;
4、每个单词最长20个字母;
数据范围:字符串长度满足 1 ≤ n ≤ 10000
输入描述:
输入一行,表示用来倒排的句子
输出描述:
输出句子的倒排结果
示例一
输入:
I am a student
输出:
student a am I
示例二
输入:
$bo*y gi!r#l
输出:
l r gi y bo
题解
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
String[] ss = in.nextLine().split("[^A-Za-z]");
for(int i = ss.length - 1; i >= 0; i--){
if(ss[i].isEmpty()){
continue;
}else{
System.out.print(ss[i] + " ");
}
}
System.out.println();
}
}
}
8. 密码截取
描述
Catcher是MCA国的情报员,他工作时发现敌国会用一些对称的密码进行通信,比如像这些ABBA,ABA,A,123321,但是他们有时会在开始或结束时加入一些无关的字符以防止别国破解。比如进行下列变化 ABBA->12ABBA,ABA->ABAKK,123321->51233214 。因为截获的串太长了,而且存在多种可能的情况(abaaab可看作是aba,或baaab的加密形式),Cathcer的工作量实在是太大了,他只能向电脑高手求助,你能帮Catcher找出最长的有效密码串吗?
数据范围:字符串长度满足 1 ≤ n ≤ 2500
输入描述:
输入一个字符串(字符串的长度不超过2500)
输出描述:
返回有效密码串的最大长度
示例
输入:ABBA
输出:4
输入:ABBBA
输出:5
输入:12HHHHA
输出:4
题解
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
char[] chars = in.nextLine().toCharArray();
int max = 0;
for(int i = 0; i < chars.length; i++){
max = Math.max(max, Math.max(longest(chars, i, i), longest(chars, i, i + 1)));
}
System.out.println(max);
}
}
public static int longest(char[] chars, int l, int r){
while(l >= 0 && r < chars.length && chars[l] == chars[r]){
l--;
r++;
}
return r - l - 1;
}
}
9. 整数与IP地址间的转换
描述
原理:ip地址的每段可以看成是一个0-255的整数,把每段拆分成一个二进制形式组合起来,然后把这个二进制数转变成
一个长整数。
举例:一个ip地址为10.0.3.193
每段数字 | 相对应的二进制数 |
---|---|
10 | 00001010 |
0 | 00000000 |
3 | 00000011 |
193 | 11000001 |
组合起来即为:00001010 00000000 00000011 11000001,转换为10进制数就是:167773121,即该IP地址转换后的数字就是它了。
数据范围:保证输入的是合法的 IP 序列
输入描述:
1 输入IP地址
2 输入10进制型的IP地址
输出描述:
1 输出转换成10进制的IP地址
2 输出转换后的IP地址
示例
输入:
10.0.3.193
167969729
输出:
167773121
10.3.3.193
题解
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
String s = in.nextLine();
System.out.println(convert(s));
}
}
public static String convert(String str) {
if (str.contains(".")) {
String[] fields = str.split("\\.");
long result = 0;
for (int i = 0; i < 4; i++) {
result = result * 256 + Integer.parseInt(fields[i]);
}
return "" + result;
}
else {
long ipv4 = Long.parseLong(str);
String result = "";
for (int i = 0; i < 4; i++) {
result = ipv4 % 256 + "." + result;
ipv4 /= 256;
}
return result.substring(0, result.length() - 1);
}
}
}
10. 图片整理
描述
Lily上课时使用字母数字图片教小朋友们学习英语单词,每次都需要把这些图片按照大小(ASCII码值从小到大)排列收好。请大家给Lily帮忙,通过代码解决。
Lily使用的图片使用字符"A"到"Z"、“a"到"z”、"0"到"9"表示。
数据范围:每组输入的字符串长度满足 1 ≤ n ≤ 1000
输入描述:
一行,一个字符串,字符串中的每个字符表示一张Lily使用的图片。
输出描述:
Lily的所有图片按照从小到大的顺序输出
示例
输入:
Ihave1nose2hands10fingers
输出:
0112Iaadeeefghhinnnorsssv
题解
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
char[] cs = in.nextLine().toCharArray();
Arrays.sort(cs);
System.out.println(new String(cs));
}
}
}
11. 蛇形矩阵
描述
蛇形矩阵是由1开始的自然数依次排列成的一个矩阵上三角形。
例如,当输入5时,应该输出的三角形为:
1 3 6 10 15
2 5 9 14
4 8 13
7 12
11
输入描述:
输入正整数N(N不大于100)
输出描述:
输出一个N行的蛇形矩阵。
示例
输入:
4
输出:
1 3 6 10
2 5 9
4 8
7
题解
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNextInt()) {
int a = in.nextInt();
int[][] arr = new int[a][a];
arr[0][0] = 1;
for(int i = 0; i < a; i++){
if(i != 0){
arr[i][0] = arr[i - 1][0] + i;
}
System.out.print(arr[i][0] + " ");
for(int j = 1; j < a - i; j++){
arr[i][j] = arr[i][j - 1] + j + i + 1;
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}
}
}
12. 字符串加密
描述
有一种技巧可以对数据进行加密,它使用一个单词作为它的密匙。下面是它的工作原理:首先,选择一个单词作为密匙,如TRAILBLAZERS。如果单词中包含有重复的字母,只保留第1个,将所得结果作为新字母表开头,并将新建立的字母表中未出现的字母按照正常字母表顺序加入新字母表。如下所示:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
T R A I L B Z E S C D F G H J K M N O P Q U V W X Y (实际需建立小写字母的字母表,此字母表仅为方便演示)
上面其他用字母表中剩余的字母填充完整。在对信息进行加密时,信息中的每个字母被固定于顶上那行,并用下面那行的对应字母一一取代原文的字母(字母字符的大小写状态应该保留)。因此,使用这个密匙, Attack AT DAWN (黎明时攻击)就会被加密为Tpptad TP ITVH。
请实现下述接口,通过指定的密匙和明文得到密文。
数据范围:1 ≤ n ≤ 100 ,保证输入的字符串中仅包含小写字母。
输入描述:
先输入key和要加密的字符串
输出描述:
返回加密后的字符串
示例
输入:
nihao
ni
输出:
le
题解
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
char[] keys = in.nextLine().toUpperCase().toCharArray();
char[] con = in.nextLine().toCharArray();
Set<Character> set = new LinkedHashSet<>();
for(int i = 0; i < keys.length; i++){
set.add(keys[i]);
}
int k = 0;
while(set.size() < 26){
set.add((char)('A' + k++));
}
List<Character> list = new ArrayList<>(set);
for(int i = 0; i < con.length; i++){
if(con[i] == ' '){
System.out.print(' ');
}else if(con[i] < 'a'){
System.out.print(list.get(con[i] - 'A'));
}else{
System.out.print((char)(list.get(con[i] - 'a') + 'a' - 'A'));
}
}
System.out.println();
}
}
}