八个算法题

来源:互联网 发布:c语言头文件stdio 编辑:程序博客网 时间:2024/05/17 22:37

一、
*牛牛有n张卡片排成一个序列.每张卡片一面是黑色的,另一面是白色的。
* 初始状态的时候有些卡片是黑色朝上,有些卡片是白色朝上。
* 牛牛现在想要把一些卡片翻过来,得到一种交替排列的形式,即每对相邻卡片的颜色都是不一样的。
* 牛牛想知道最少需要翻转多少张卡片可以变成交替排列的形式。
* 输入描述:
* 输入包括一个字符串S,字符串长度length(3 ≤ length ≤ 50),其中只包含’W’和’B’两种字符串,分别表示白色和黑色。
* 整个字符串表示卡片序列的初始状态。
* 输出描述:
* 输出一个整数,表示牛牛最多需要翻转的次数。
示例1
输入
BBBW
输出
1

代码:

public class Main {    public static void main(String[] args) {        Scanner sc=new Scanner(System.in);        String str = sc.next();        sc.close();        int cnt = 0 , cnt2 = 0;        char c[] = str.toCharArray();        for(int i = 0; i < c.length; i++){            if(i % 2 == 0) {                if(c[i] != 'W') {                    cnt++;                }else {                    cnt2++;                }            }else {                if(c[i] != 'B') {                    cnt++;                }else{                    cnt2++;                }            }        }        System.out.println(Math.min(cnt, cnt2));    }

二、
牛牛变得黑化了,想要摧毁掉地球。但他忘记了开启地球毁灭器的密码。牛牛手里有一个字符串S,牛牛还记得从S中去掉一个字符就恰好是正确的密码,请你帮牛牛求出他最多需要尝试多少次密码。
如样例所示S = “ABA”,3个可能的密码是”BA”, “AA”, “AB”.
当S = “A”, 牛牛唯一可以尝试的密码是一个空的密码,所以输出1.
输入描述:
输入包括一个字符串S,字符串长度length(1 ≤ length ≤ 50),其中都是从’A’到’Z’的大写字母。
输出描述:
输出一个整数,表示牛牛最多需要尝试的密码次数。
示例1
输入
ABA
输出
3

代码:

public class Main {    public static void main(String[] args) {        Scanner sc=new Scanner(System.in);        String str = sc.next();        sc.close();        //如果有相邻字符相同,尝试次数减1,        char c[] = str.toCharArray();        int res = c.length;        for(int i = 1; i < c.length; i++) {            if(c[i] == c[i - 1]) {                res--;            }        }        System.out.println(res);    }}

三、
牛牛以草料为食。牛牛有一天依次遇到n堆被施展了魔法的草料,牛牛只要遇到一堆跟他当前相同大小的草料,它就会把草料吃完,而使自己的大小膨胀一倍。一开始牛牛的大小的是A,然后给出牛牛依次遇到的n堆草料的大小。请计算牛牛最后的大小。
输入描述:
输入包括两行,第一行包含两个整数n和A(1 ≤ n ≤ 200, 1 ≤ A ≤ 1,000,000,000)
第二行包括n个整数,表示牛牛依次遇到的草料堆大小a_i(1 ≤ a_i ≤ 1,000,000,000)
输出描述:
输出一个整数,表示牛牛最后的大小。
示例
输入
5 1
2 1 3 1 2
输出
4

代码:

public class Main {    public static void main(String[] args) {        Scanner sc=new Scanner(System.in);        int n = sc.nextInt();        int A = sc.nextInt();        int arr[] = new int [n];        for(int i = 0; i < n; i++) {            arr[i] = sc.nextInt();        }        sc.close();        //比较懒,直接排序了        Arrays.sort(arr);        for(int i = 0; i < n; i++) {            if(arr[i] == A) {                A *= 2;            }        }        System.out.println(A);    }}

四、
牛牛有一个长度为n的整数序列s,羊羊要在牛牛的序列中选择不同的两个位置,然后交换这两个位置上的元素。现在需要求出羊羊交换后可以得到的不同的序列个数。(注意被交换的两元素值可能相同)。
如序列{1, 47},输出1.羊羊必须交换仅有的两个元素,得到序列{47, 1}。羊羊必须交换,不能保留原有的序列。
{1, 2, 1},输出3.羊羊通过交换可以得到{2, 1, 1},{1, 1, 2},{1, 2, 1}这三个序列。
输入描述:
输入包括两行,第一行为一个整数n(2 ≤ n ≤ 50),即序列的长度。
第二行n个整数,表示序列的每个元素a_i(1 ≤ a_i ≤ 50),以空格分割。
输出描述:
输出一个整数,表示羊羊可以得到的不同的序列个数
示例1
输入
3
1 2 1
输出
3
代码:

public class Main {    public static void main(String[] args) {        Scanner sc=new Scanner(System.in);        int n = sc.nextInt();        int a[] = new int[n];        for(int i = 0; i < n; i++) {            a[i] = sc.nextInt();        }        sc.close();        //复杂度有点高.把所有交换结果放到set中        Set<String> set = new HashSet<>();        for(int i = 0; i < n; i++) {            for(int j = i + 1; j < n; j++) {                int tmp = a[i];                a[i] = a[j];                a[j] = tmp;                set.add(Arrays.toString(a));//不能直接a.toString(),返回的是对像的toString方法                a[j] = a[i];                a[i] = tmp;            }        }        System.out.println(set.size());    }}

五、
牛牛喜欢字符串,但是他讨厌丑陋的字符串。对于牛牛来说,一个字符串的丑陋值是字符串中相同连续字符对的个数。比如字符串“ABABAABBB”的丑陋值是3,因为有一对”AA”和两对重叠的”BB”。现在给出一个字符串,字符串中包含字符’A’、’B’和’?’。牛牛现在可以把字符串中的问号改为’A’或者’B’。牛牛现在想让字符串的丑陋值最小,希望你能帮帮他。
输入描述:
输入包括一个字符串s,字符串长度length(1 ≤ length ≤ 50),字符串只包含’A’,’B’,’?’三种字符。
输出描述:
输出一个整数,表示最小的丑陋值
示例1
输入
A?A
输出
0

代码:

public class Main {    public static void main(String[] args) {        Scanner sc=new Scanner(System.in);        String str = sc.next();        sc.close();        char c[] = str.toCharArray();        //一种特殊情况是前导有若干个‘?’        int k = 0;        while(k < c.length && c[k] =='?') {            k++;        }        k = (k==0)?1:k;        for(int i = k; i < c.length; i++) {            if(c[i] == '?') {                c[i]=(c[i - 1] == 'A')?'B':'A';            }        }        int res = 0;        for(int i = k; i < c.length; i++) {            if(c[i] == c[i - 1]) {                res++;            }        }        System.out.println(res);    }}

六、
牛家庄幼儿园为庆祝61儿童节举办庆祝活动,庆祝活动中有一个节目是小朋友们围成一个圆圈跳舞。牛老师挑选出n个小朋友参与跳舞节目,已知每个小朋友的身高h_i。为了让舞蹈看起来和谐,牛老师需要让跳舞的圆圈队形中相邻小朋友的身高差的最大值最小,牛老师犯了难,希望你能帮帮他。
如样例所示:
当圆圈队伍按照100,98,103,105顺时针排列的时候最大身高差为5,其他排列不会得到更优的解
输入描述:
输入包括两行,第一行为一个正整数n(3 ≤ n ≤ 20)
第二行为n个整数h_i(80 ≤ h_i ≤ 140),表示每个小朋友的身高。
输出描述:
输出一个整数,表示满足条件下的相邻小朋友身高差的最大值。
示例1
输入
4
100 103 98 105
输出
5

代码

public class Main {    public static void main(String[] args) {        Scanner sc=new Scanner(System.in);        int n = sc.nextInt();        int a[] = new int[n];        for (int i = 0; i < n; i++) {            a[i] = sc.nextInt();        }        sc.close();        //以最小值为基准,按序左右插入即可        //发现只有第一个元素和最后一个元素与相邻元素相邻,其他均间隔2        Arrays.sort(a);        int max = Math.max(a[1] - a[0], a[n-1] - a[n-2]);        for(int i = 0; i + 2 < n; i++) {            max = Math.max(a[i+2] - a[i], max);        }        System.out.println(max);    }}

七、
有一条无限长的纸带,分割成一系列的格子,最开始所有格子初始是白色。现在在一个格子上放上一个萌萌的机器人(放上的这个格子也会被染红),机器人一旦走到某个格子上,就会把这个格子涂成红色。现在给出一个整数n,机器人现在会在纸带上走n步。每一步,机器人都会向左或者向右走一个格子,两种情况概率相等。机器人做出的所有随机选择都是独立的。现在需要计算出最后纸带上红色格子的期望值。
输入描述:
输入包括一个整数n(0 ≤ n ≤ 500),即机器人行走的步数。
输出描述:
输出一个实数,表示红色格子的期望个数,保留一位小数。
示例1
输入
4
输出
3.4

懒得思考写了一个时间复杂度,空间复杂度较高的算法:

public class Main {    public static void main(String[] args) {        Scanner sc=new Scanner(System.in);        int tmp = sc.nextInt();        sc.close();        int n = tmp + 1;        double res = 0;        boolean b[] = new boolean[2 * n + 1];        for(int t = 0; t < 60000; t++) {//为什么迭代60000次呢,看具体要求的精度了            int p = n;            Arrays.fill(b, false);            for(int i = 0; i < n; i++) {                if(Math.random() > 0.5) {                    p--;                } else {                    p++;                }                b[p] = true;            }            for(int i = 0; i <= 2*n; i++) {                if(b[i]) {                    res++;                }            }        }        System.out.println(String.format("%.1f",res /60000));    }}

八、牛牛在农场饲养了n只奶牛,依次编号为0到n-1, 牛牛的好朋友羊羊帮牛牛照看着农场.有一天羊羊看到农场中逃走了k只奶牛,但是他只会告诉牛牛逃走的k只奶牛的编号之和能被n整除。你现在需要帮牛牛计算有多少种不同的逃走的奶牛群。因为结果可能很大,输出结果对1,000,000,007取模。
例如n = 7 k = 4:
7只奶牛依次编号为0到6, 逃走了4只
编号和为7的有:{0, 1, 2, 4}
编号和为14的有:{0, 3, 5, 6}, {1, 2, 5, 6}, {1, 3, 4, 6},{2, 3, 4, 5}
4只牛的编号和不会大于18,所以输出5.
输入描述:
输入包括一行,两个整数n和k(1 ≤ n ≤ 1000),(1 ≤ k ≤ 50),以空格分割。
输出描述:
输出一个整数表示题设所求的种数。
示例1
输入
7 4
输出
5

public class Main {    public static void main(String[] args) {        Scanner sc=new Scanner(System.in);        int n = sc.nextInt();        int num = sc.nextInt();        sc.close();//      从0~n中选num个数和为n的倍数的情况,为背包问题//      dp[i][j][k],前i个数选j个,j个数的和对n取模为k的情况数//      状态转移方程:dp[i][j][k]=dp[i-1][j][k]+dp[i-1][j-1][(k-i+n)%n]  +n是为了防k比i小//      压缩,dp[j][k]=dp[j][k]+dp[j-1][k-i+n)%n];//      初值,i为0和j为0的情况        int dp[][] = new int[num+1][n+1];        dp[0][0] = 1;        dp[1][0] = 1;        for(int i = 1; i < n; i++) {            for(int j = num; j > 0; j--) {                for(int k = 0; k < n; k++) {                    dp[j][k] = (dp[j][k] + dp[j - 1][(k-i+n) % n]) % 1000000007;                }            }        }        System.out.println(dp[num][0]);    }}
原创粉丝点击