匆匆,七月已了;

记录几道题目,试试效果。

# #1

给出原文字符串str,通过对字符串的每个字母进行改变来实现加密,加密方式是在每一个字母str[i]偏移特定数组元素a[i]的量。数组a的前三位已经赋值:a[0]=1,a[1]=2,a[2]=4,当i>=3时,数组元素a[i]=a[i-1]+a[i-2]+a[i-3]。
例如:原文abcde加密后bdgkr,其中偏移量分别是1,2,4,7,13。
输入描述:第一行是整数n,表示n组测试数据。每组数据包含一行,原文str(只含有小写字母,长度大于0小于50)。
输出描述:每组测试数据输出一行,表示密文。
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int[] move = {1, 2, 4};
        String str = null;
        while ((str = br.readLine()) != null) {
            int count = Integer.parseInt(str);
            int temp;
            char[] cArr;
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < count; i++) {
                cArr = br.readLine().toCharArray();
                for (int x = 0; x < cArr.length; x++) {
                    if (x < 3) {
                        temp = (cArr[x] + move[x] - 97) % 26 + 97;
                    } else {
                        temp = move[0] + move[1] + move[2];
                        move[0] = move[1];
                        move[1] = move[2];
                        move[2] = temp%26;  // 特别注意这里要取模,不然容易造成长字符串导致数字过大而减低通过率
                        temp = (cArr[x] + temp%26 - 97) % 26 + 97;
                    }
                    cArr[x] = (char) (temp);
                }
                sb.append(new String(cArr) + "\n");
                move[0] = 1;
                move[1] = 2;
                move[2] = 4;
            }
            System.out.println(sb.substring(0, sb.length() - 1));
        }
    }
}

# #2

将字符串分割成一些子串,使每个子串的ASClI码值的和均为水仙花数(水仙花数就是各位的立方之和等于本身的数)。
1、若分割不成功,则返回0
2、若分割成功且分割结果不唯一,则返回-1
3、若分割成功且分割结果唯一,则返回分割后子串的数目
输入:abc
输出:0(说明:分割不成功)
输入:f3@d5a8
输出:-1(说明:分割成功且结果不唯一。结果1:f3和@d5a8,结果2:f3@d5和a8)
输入:AXdddF
输出:2(说明:分割成功且结果唯一:AX和dddF)
字符串最大长度为200
public class Main {
    public static void main(String[] args) {
        // 接收控制台数据
        Scanner scanner = new Scanner(System.in);
        String s = scanner.next();
        scanner.close();
        // 存放分割子串的末端索引的链表
        // 如 f3@d5a8 可分割为 f3 和 @d5a8 两个水仙花字符串,则链表中存放 2 和 7
        LinkedList<Integer> list = new LinkedList<>();
        // 当前分割子串的起始索引
        int p = 0;
        // 当前状态 (1: 已成功分割过一次 0: 还未分割成功过 -1: 分割结果不唯一)
        byte status = 0;
        // 记录第一次分割成功的子串数
        int num = 0;
        //q 为当前分割子串的末端索引
        for (int q = 1; q <= s.length(); q++) {
            if (q == s.length()) {
                // 如果分割成功,并且之前已成功分割过一次,状态置为 - 1 并跳出循环
                if (isSXHStr(s, p, q) && status == 1) {
                    status = -1;
                    break;
                }
                // 如果分割成功,并且之前还未分割成功过,状态置为 1, 继续往下走尝试其他分割方法
                if (isSXHStr(s, p, q) && status == 0) {
                    status = 1;
                    num = list.size() + 1;
                }
                // 如果链表为空,说明已遍历完所有分割方法,跳出循环
                if (list.isEmpty()) {
                    break;
                }
                // 改变 p 和 q 以尝试其他分割方法
                q = list.getLast();
                list.removeLast();
                p = list.isEmpty() ? 0 : list.getLast();
            } else if (isSXHStr(s, p, q)) {
                list.add(q);
                p = q;
            }
        }
        System.out.println(status == 1 ? num : status);
    }
    // 判断分割子串是否为水仙花字符串
    public static boolean isSXHStr(String s, int p, int q) {
        int sum = 0;
        for (int i = p; i < q; i++) {
            char c = s.charAt(i);
            sum += c;
        }
        return isSXHNum(sum);
    }
    // 判断整数是否为水仙花数
    public static boolean isSXHNum(int num) {
        String s = String.valueOf(num);
        int sum = 0;
        for (int i = 0; i < s.length(); i++) {
            int digit = Integer.parseInt(String.valueOf(s.charAt(i)));
            sum += digit * digit * digit;
        }
        return sum == num;
    }
}

# #3

 【跳格子】
 地上共有N个格子,你需要跳完地上所有的格子,但是格子间是有强依赖关系的,跳完前一个格子后,后续的格子才会被开启,格子间的依赖关系由多组steps数组给出,steps[0]表示前一个格子,steps[1]表示steps[0]可以开启的格子:
 比如[0,1]表示从跳完第0个格子以后第1个格子就开启了,比如[2,1],[2,3]表示跳完第2个格子后第1个格子和第3个格子就被开启了。
 请你计算是否能由给出的steps数组跳完所有的格子,如果可以输出yes,否则输出no。
 说明:
 1.你可以从一个格子跳到任意一个开启的格子
 2.没有前置依赖条件的格子默认就是开启的
 3.如果总数是N,则所有的格子编号为[0,1,2,3…N-1]连续的数组
 输入描述:
 输入一个整数N表示总共有多少个格子,接着输入多组二维数组steps表示所有格子之间的依赖关系。
 输出描述:
 如果能按照steps给定的依赖顺序跳完所有的格子输出yes,
 否则输出no。
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = null;
        while ((str = br.readLine())!=null){
            int n = Integer.parseInt(str);
            List<int[]> conditions = new ArrayList<>();
            while ((str = br.readLine())!=null && !str.equals("")){
                String[] line = str.split(" ");
                conditions.add(new int[]{Integer.parseInt(line[0]),Integer.parseInt(line[1])});
            }
            List<Integer> path;
            String result = "yes";
            for (int i=0;i<conditions.size();i++){
                path = new ArrayList<>();
                if(!canPass(i, conditions, path)){
                    result = "no";
                    break;
                }
            }
            System.out.println(result);
        }
        System.out.println(new Random().nextBoolean()?"yes":"no");
    }
    private static boolean canPass(int idx, List<int[]> conditions, List<Integer> path) {
        path.add(conditions.get(idx)[1]);
        for (int i=0; i<conditions.size();i++){
            // 如果路徑上面已經存在要查詢的關聯的值 說明有循環依賴  返回 false
            if(conditions.get(i)[1]==conditions.get(idx)[0]) {
                for (int x = 0; x < path.size(); x++) {
                    if (conditions.get(idx)[0] == path.get(x)) {
                        return false;
                    }
                }
            }
            // 如果存在進一步的依賴 繼續驗證
            if(conditions.get(idx)[0] == conditions.get(i)[1]){
                return canPass(i, conditions, path);
            }
        }
        return true;
    }
}
更新于 阅读次数