BJTU OJ Q

BJTU OJ QUESTIONS

Problem 1 最小差元素

题面描述:
给定一个整数数组,请求出该数组中两数之差(绝对值)的最小值,并确定元素的位置。

输入:
第一行为一个正整数N(1<N<=10000),随后第二行为N个整数。

输出:
该数组中两数之差(绝对值)的最小值及对应元素在输入数组中的位置索引,索引从1开始计数,以空格分隔。若有多组,输出任意一组即可。

示例输入:

5
105 7 9 16 -31

7
105 7 9 16 -31 9 11

示例输出:

2 2 3

0 3 6

代码如下:

import java.io.BufferedInputStream;
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner s = new Scanner(new BufferedInputStream(System.in));
        //t表示有t个数据
        int t = s.nextInt();
        int x1=0,x2=0,min=0;
        //原数组
        long[] arr = new long[t];
        //原数组排序后输出的差值数组
        long[] MinDiff = new long[t - 1];
        for (int i = 0; i < t; i++) {
            arr[i] = s.nextLong();
        }
        //temp1保存arr
        long[] temp1 = arr.clone();
        Arrays.sort(temp1);
        for (int j = 0; j < t - 1; j++) {
            MinDiff[j] = temp1[j + 1] - temp1[j];
        }
        //temp2保存差值数组
        long[] temp2 = MinDiff.clone();
        Arrays.sort(temp2);
        //此时temp2[0]即为最小差值,若差值数组某一元素等,令min=k,即排序后数组temp1下标为min & min+1
        for (int k=0;k<t-1;k++) {
            if (MinDiff[k] == temp2[0]) {
                min = k;
            }
        }
        //进行回溯
        for (int z=0;z<t;z++) {
            //若两者相等,差值为0,在arr里break岔开遍历寻找
            if (temp1[min] == temp1[min + 1]) {
                if (arr[z] == temp1[min]) {
                    x1 = z;
                    break;
                }
                for (int y = z + 1; y < t; y++) {
                    if (arr[y] == temp1[min + 1]) {
                        x2 = y;
                    }
                }
            }
            //遍历寻找
            else {
                if (arr[z] == temp1[min]) {
                    x1 = z;
                }
                if (arr[z] == temp1[min + 1]) {
                    x2 = z;
                }
            }
        }
        //如else里顺序有变,则交换x1 x2,保证x1 > x2
        if (x1>x2){
            int tem = x2;
            x2 = x1;
            x1 = tem;
        }
        //考虑0下标,输出项+1
        System.out.printf("%d %d %d",temp2[0],x1+1,x2+1);
    }
}

Problem 2 求和

题面描述:
计算若干十六进制数的和。

输入:
输入有若干行,每行为由空格分隔的若干数十六进制整数(不超过10000个),如:
5 A

输出:
控制台输出,对每行输入,输出该行十六进制数的和,用十进制表示。如:15

示例输入:

0xB 0xC
0xc -0x14 -0x7 0x2 0x10

示例输出:

23
3

import java.io.BufferedInputStream;
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner s = new Scanner(new BufferedInputStream(System.in));
        long b = 0;
        while (s.hasNextLine()) {
            String n = s.nextLine();
            //进行数据处理,将字符串删除0x和空格,变成数字串
            n = n.replaceAll("0x", "");
            String[] c = n.split(" ");
            for (int i = 0; i < c.length; i++) {
                //转换成十进制
                b += Long.parseLong(c[i], 16);
            }
            System.out.println(b);
            //最后使b变为0,不然b会累加,使第二行数据的结果加上第一行的结果
            b=0;
        }
    }
}

Problem 3 字符串映射

题面描述:
有两个长度相同的字符串,均由字母A-Z构成,长度不超过100。请判断是否可以把其中一个字符串的各个字母重排,然后对26个字母做一个一一映射,使得两个字符串相同。
如JWPUDJSTVP重排后可以得到WJDUPSJPVT,然后把每个字母映射到它前一个字母(B->A, C->B, …, Z->Y, A->Z),得到VICTORIOUS。

输入:
两行字符串。

输出:
若可以请输出两行,第一行为YES,第二行为对应的一个映射。否则输出NO。

示例输入:

ABBCFEA
CCGGHJB

示例输出:

YES
A->C B->G C->H F->J E->B

import java.io.BufferedInputStream;
import java.util.*;

public class Main {
    //映射
    public static String Map(String c) {
        //删掉重复元素
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < c.length(); i++) {
            char d = c.charAt(i);
            if (c.indexOf(d) == c.lastIndexOf(d)){
                sb.append(d);
            }
            else {
                int FirstPosition = c.indexOf(d);
                if (FirstPosition == i) {
                    sb.append(d);
                }
            }
        }
        return String.valueOf(sb);
    }
    public static void main(String[] args) {
        Scanner s = new Scanner(new BufferedInputStream(System.in));
        String a = s.nextLine();
        String b = s.nextLine();
        int[] arr1 = new int[26];
        int[] arr2 = new int[26];
        //得到a、b中每个字母的个数
        for(int i = 0; i < a.length(); i++) {
            arr1[a.charAt(i) - 'A']++;
            arr2[b.charAt(i) - 'A']++;
        }
        //判定两数组的对应情况
        for(int i = 0; i < a.length(); i++) {
            if(arr1[a.charAt(i) - 'A'] != -1) {
                for(int j = 0; j < 26; j++) {
                    if(arr2[j] == arr1[a.charAt(i) - 'A']) {
                        arr1[a.charAt(i) - 'A'] = -1;
                        arr2[j] = -1;
                        break;
                    }
                }
            }
            //输出NO
            if(arr1[a.charAt(i) - 'A'] != -1) {
                System.out.println("NO");
                //正常退出,程序正常执行结束退出;1为非正常,强行退出
                System.exit(0);   
            }
        }
        System.out.println("YES");
        String deleteA = Map(a);
        String deleteB = Map(b);
        //输出映射
        for (int i = 0; i <deleteA.length()-1 ; i++) {
            System.out.print(deleteA.charAt(i)+"->"+deleteB.charAt(i)+" ");
        }
        System.out.println(deleteA.charAt(deleteA.length()-1)+"->"+deleteB.charAt(deleteB.length()-1));
        s.close();
    }
}

Preblem 4 独立元素

题面描述:
给定一个整数数组,请按从大到小的顺序输出该数组中元素,相同的元素只输出一次。

输入:
第一行为一个正整数N(1<N<=10000),随后第二行为N个整数。

输出:
按从大到小的顺序输出满足条件的元素。

示例输入:

5
105 7 9 16 -31

10
-1 9 -4 10 -2 -1 -1 -7 -3 -4

示例输出:

105 16 9 7 -31

10 9 -1 -2 -3 -4 -7

import java.io.BufferedInputStream;
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner s = new Scanner(new BufferedInputStream(System.in));
        int n = s.nextInt();
        long[] a = new long[n];
        for (int i = 0; i < n; i++) {
            a[i] = s.nextLong();
        }
        //Set防重复
        Set<Long> c = new HashSet<>();
        for (long i : a) {
            c.add(i);
        }
        Long[] b = new Long[c.size()];
        c.toArray(b);
        Arrays.sort(b);
        System.out.print(b[b.length-1]);
        //按照空格顺序输出
        for (int i = 1; i < b.length; i++) {
            System.out.printf(" %d",b[b.length-1-i]);
        }
        System.out.println();
    }
}

Problem 5
巅峰日
成绩: 5 / 折扣: 0.8
题面描述:
大贤者福尔经过长期的研究后发现,人的体力、智商和情商和运气具有周期性,会有高峰和低估,并且呈现出周期性变化的规律。在每一个周期中会有一天是高峰,这一天人会在某个方便表现的非常出色。尽管如此,由于这些周期的长度不一致, 通常情况下几个周期的高峰不会在同一天出现。但大众又都希望哪一天是自己的巅峰日,在这一天中,自己的体力、智商和情商和运气都达到高峰。

输入:
输入数据有若干组,每一组包括两行数据,第一行包括4个正整数,分别为体力、智商和情商和运气的周期,已知最大周期不超过50。第二行包括5个非负整数 p, i, e, l, dp,i,e,l,d ,分别表示体力、智商、情商、和运气在一年中第一次达到高峰的时间(从一年的第一天开始算起,第一天记为0),dd为计算的开始时间(从一年第一天开始的天数)。所有时间非负且小于365。

输出:
对每组测试数据,在单独的行中输出结果。先输出当前测试样例的组号Case x:,x为测试样例编号,随后输出第一个巅峰日距离给定日期 dd 的天数。

若在有生之年都无法找到这样的日子,则输出No such days.。所谓有生之年是指不超过上述周期之积后一年的日期范围。

示例输入:
23 28 33 1
0 0 0 0 0
23 28 33 1
0 0 0 0 100
23 28 33 1
5 20 34 0 325
23 28 33 1
4 5 6 0 7
23 28 33 1
283 102 23 0 320
23 28 33 1
203 301 203 0 40
39 3 48 21
31 323 144 294 146

示例输出:
Case 1: 21252
Case 2: 21152
Case 3: 19575
Case 4: 16994
Case 5: 8910
Case 6: 10789
Case 7: No such days.

import java.io.BufferedInputStream;
import java.util.Scanner;

public class Main {
    public static boolean IsPeak(int p, int P, int res) {
        if ((res - p) % P == 0) {
            return true;
        }
        else {
            return false;
        }
    }

    public static void main(String[] args) {
        Scanner s = new Scanner(new BufferedInputStream(System.in));
        int count = 1;
        while (s.hasNextInt()) {
            System.out.print("Case "+count+": ");
            count++;
            boolean flag = true;
            int P = s.nextInt();
            int I = s.nextInt();
            int E = s.nextInt();
            int L = s.nextInt();
            int p = s.nextInt();
            int i = s.nextInt();
            int e = s.nextInt();
            int l = s.nextInt();
            int d = s.nextInt();
            int FinalNum = P * I * E * L;
            for (int j = d + 1; j <= FinalNum; j++) {
                if (IsPeak(p, P, j) && IsPeak(i, I, j) && IsPeak(e, E, j) && (IsPeak(l, L, j))) {
                    System.out.println(j-d);
                    flag = false;
                    break;
                }
            }
            if (flag) System.out.println("No such days.");
        }
    }
}


problem 6
特殊单词
成绩: 5 / 折扣: 0.8
题面描述:
一篇文章由有若干个单词构成,小A希望知道文章中有哪些特殊单词。所谓特殊单词是指,构成这个单词的字母经过顺序变换形成的一个新单词也出现在文章中。与原单词构成的字母对比,新单词的字母可以有大小变化。小A希望知道文章中这样的特殊单词有哪些,您能帮他找出来吗?

输入:
输入数据有若干行,每行为一个字符串,由空格分隔开,单词由大小写字符及数字构成,每个单词长度不超过30个字符。若该行字符为#,表示输入结束。

输出:
按不区分大小写的字典序输出所有的特殊单词,所有特殊单词按其第一次在文章中出现的形式输出,每行输出一个单词。

示例输入:
a aa sd 12 aaa Bd dB
BD c a 21 A
aa aaa

示例输出:
12
Bd
a

import java.io.BufferedInputStream;
import java.util.*;

public class Main {
    public static String Sort(String x) {
        String string = "";
        char[] arr = new char[x.length()];
        for (int i = 0; i < x.length(); i++) {
            arr[i] = x.charAt(i);
        }
        Arrays.sort(arr);
        for (int i = 0; i < arr.length; i++) {
            string += arr[i];
        }
        return string;
    }

    public static void main(String[] args) {
        Scanner s = new Scanner(new BufferedInputStream(System.in));
        Set<String> set = new HashSet<>();//原生的
        List<String> set1 = new ArrayList<>();//存储得到的结果
        List<String> set3 = new ArrayList<>();//存储得到的结果

        while (s.hasNextLine()) {
            String ss = s.nextLine();
            if (ss.equals("#")) break;
            String arr[] = ss.split(" ");
            for (int i = 0; i < arr.length; i++) {
                set1.add(arr[i]);
            }
        }
        for (String value1 : set1) {//用没有排好序的
            for (String value : set1) {//用没有排好序的
                if (!value.equals(value1)){// 两个单词不相等
                    if ((Sort(value1).equals(Sort(value))||(Sort(value1.toLowerCase()).equals(Sort(value.toLowerCase()))))){
                        if (!set.contains(Sort(value1.toLowerCase()))){
                            set.add(Sort(value1.toLowerCase()));
                            set3.add(value1);
                        }
                    }
                }
            }
        }
        String arr[] = set3.toArray(new String[set3.size()]);
        Arrays.sort(arr);
        for (String x : arr
        ) {
            System.out.println(x);
        }
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值