算法刷题——网易篇

网易(入门)

WY8下厨房

描述

牛牛想尝试一些新的料理,每个料理需要一些不同的材料,问完成所有的料理需要准备多少种不同的材料。

输入描述:

每个输入包含 1 个测试用例。每个测试用例的第 i 行,表示完成第 i 件料理需要哪些材料,各个材料用空格隔开,输入只包含大写英文字母和空格,输入文件不超过 50 行,每一行不超过 50 个字符。

输出描述:

输出一行一个数字表示完成所有料理需要多少种不同的材料。

示例1

输入:

BUTTER FLOUR

HONEY FLOUR EGG

输出:

4

解题

import java.util.*;
/*
利用hashset不重复特性,存放字符串,最后计算长度即可
*/
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s;
        HashSet<String> set = new HashSet<>();  // 用hashset不重复特性
        
        while (sc.hasNext()) {  // hasNext():读取空格回车就读取
            set.add(sc.hasNext());  // 添加到set中
        }
        System.out.println(set.size());
    }
}

WY10分苹果

描述

n 只奶牛坐在一排,每个奶牛拥有 ai 个苹果,现在你要在它们之间转移苹果,使得最后所有奶牛拥有的苹果数都相同,每一次,你只能从一只奶牛身上拿走恰好两个苹果到另一个奶牛上,问最少需要移动多少次可以平分苹果,如果方案不存在输出 -1。

输入描述:

每个输入包含一个测试用例。每个测试用例的第一行包含一个整数 n(1 <= n <= 100),接下来的一行包含 n 个整数 ai(1 <= ai <= 100)。

输出描述:

输出一行表示最少需要移动多少次可以平分苹果,如果方案不存在则输出 -1。

示例1

输入:

4

7 15 9 5

输出:

3

解题

import java.util.*;
/*
1、先排除一些达不到要求的数据
2、根据给和拿其实是一致的行为,故此只需要统计需要【给/拿】多少次
*/
public class Main {
    public static void main(String[] agrs) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {  // 获取输入的数据
            int cowCount = sc.nextInt();  // 读取输入的牛数量
            int[] appleOfCow = new int[cowCount];  // 存储牛对应的苹果数量
            int appleCount = 0;  // 总的苹果数量
            
            for (int i = 0;i < appleOfCow.length; i++) {
                int num = sc.nextInt(); // 读取输入的苹果数量
                appleOfCow[i] = num;
                appleCount += num;  // 顺便累加得到苹果总数
            }
            
            // 判断是否可以平分苹果
            if (appleCount % cowCount != 0) {
                System.out.print(-1);
                return;
            }
            
            int times = 0; // 记录次数,超出2个就+1,缺少两个就-1
            int avgAppleCount = appleCount / cowCount;  // 苹果平均数
            int need = 0;  // 超出苹果个数
            for (int num: appleOfCow) {
                need = num - avgAppleCount;
                if (need % 2 == 1) {  // 不能被2整除就不符合转移规定
                    System.out.print(-1);
                    return;
                }else if (need > 0) {  // 超过平均数苹果
                    // 拿出来的苹果刚好会给到缺少的,故此只需要统计拿出来的次数或者给出去的次数
                    times += need / 2;  
                }
            }
            System.out.print(times);
            return;
        }
    }
}

WY11星际穿越

描述

航天飞行器是一种复杂而又精密的仪器,飞行器的损耗主要集中在发射和降落的过程,科学家根据实验数据估计,如果在发射过程中,产生了 x 程度的损耗,那么在降落的过程中就会产生 x2 程度的损耗,如果飞船的总损耗超过了它的耐久度,飞行器就会爆炸坠毁。问一艘耐久度为 h 的飞行器,假设在飞行过程中不产生损耗,那么为了保证其可以安全的到达目的地,只考虑整数解,至多发射过程中可以承受多少程度的损耗?

数据范围:1 ≤ h ≤ 1018

输入描述:

每个输入包含一个测试用例。每个测试用例包含一行一个整数 h (1 <= h <= 1018)。

输出描述:

输出一行一个整数表示结果。

示例1

输入: 10

输出: 2

解题

import java.util.*;
/*
题目整体感觉不难,难在一些数据细节的处理上
*/
public class Main {
    public static void main(String[] agrs) {
        Scanner sc = new Scanner(System.in);
        long n = sc.nextLong();  // 使用long
        for (long i = (long) Math.sqrt(n); ; i--) {  // 开方
            if ((i*i + i) <= n) {
                System.out.print(i);
                return;
            }
        }
    }
}

WY12藏宝图

描述

牛牛拿到了一个藏宝图,顺着藏宝图的指示,牛牛发现了一个藏宝盒,藏宝盒上有一个机关,机关每次会显示两个字符串 s 和 t,根据古老的传说,牛牛需要每次都回答 t 是否是 s 的子序列。注意,子序列不要求在原字符串中是连续的,例如串 abc,它的子序列就有 {空串, a, b, c, ab, ac, bc, abc} 8 种。

输入描述:

每个输入包含一个测试用例。每个测试用例包含两行长度不超过 10 的不包含空格的可见 ASCII 字符串。

输出描述:

输出一行 “Yes” 或者 “No” 表示结果。

示例1

输入:

nowcodecom

ooo

输出:

Yes

解题

import java.util.*;
/*
切割字符串,用索引判断是否有该字符,有则切割,再一次判断下去
*/
public class Main {
    public static void main(String[] agrs) {
        Scanner sc = new Scanner(System.in);
        String str1 = sc.nextLine();  
        String str2 = sc.nextLine();  // 记录子串
        
        char[] chs = str2.toCharArray();  // 将字串转为字符数组
        
        for (int i = 0; i < chs.length; i++) { // 遍历字符数组
            int index = str1.indexOf(chs[i]);  // 返回首个字符索引,无则返回-1
            if (index == -1) {  // 没有则不是字串
                System.out.print("No");
                return;
            }
            str1 = str1.substring(index + 1);  // 根据题目要求将作废的字符串舍去
        }
        System.out.print("Yes");
    } 
}

WY13数列还原

描述

牛牛的作业薄上有一个长度为 n 的排列 A,这个排列包含了从1到n的n个数,但是因为一些原因,其中有一些位置(不超过 10 个)看不清了,但是牛牛记得这个数列顺序对的数量是 k,顺序对是指满足 i < j 且 A[i] < A[j] 的对数,请帮助牛牛计算出,符合这个要求的合法排列的数目。

输入描述:

每个输入包含一个测试用例。每个测试用例的第一行包含两个整数 n 和 k(1 <= n <= 100, 0 <= k <= 1000000000),接下来的 1 行,包含 n 个数字表示排列 A,其中等于0的项表示看不清的位置(不超过 10 个)。

输出描述:

输出一行表示合法的排列数目。

示例1

输入:

5 5

4 0 0 2 0

输出:

2

解题

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

public class Main {
    public static int res = 0;
    public static int[] nums, cands;
    public static boolean[] seen;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = null;
        while ((str = br.readLine()) != null) {
            if (str.equals(""))
                continue;
            String[] params = str.split(" ");
            int n = Integer.parseInt(params[0]), k = Integer.parseInt(params[1]);
            params = br.readLine().split(" ");
            Set<Integer> set = new HashSet();
            for (int i = 1; i <= n; i++)
                set.add(i);
            nums = new int[n]; // 保存排列
            List pos = new ArrayList(); // 记录需要填充的位置
            for (int i = 0; i < n; i++) {
                nums[i] = Integer.parseInt(params[i]);
                if (nums[i] == 0)
                    pos.add(i);
                else
                    set.remove(nums[i]);
            }
            int count = pos.size();  // 记录需要填充的个数
            cands = new int[count]; // 记录需要填充的数字
            int index = 0;
            for (int temp : set) cands[index++] = temp;

            int base = 0;  // 记录已有部分包含的顺序对数量
            for (int i = 0; i < n; i++) {
                if (nums[i] > 0) {
                    for (int j = i + 1; j < n; j++) {
                        if (nums[i] < nums[j]) base++;
                    }
                }
            }

            seen = new boolean[count];  // 用于遍历数组
            res = 0;
            dfs(pos, 0, count, base, k, n);
            System.out.println(res);
        }
        br.close();
    }

    public static void dfs(List<Integer> pos, int index, int count, int base, int k, int n) {
        if (index == count) {
            if (base == k) res++;
        } else {
            int position = pos.get(index);  // 此时要插入的位置
            for (int i = 0; i < count; i++) {
                if (seen[i]) continue;
                // 进行深度遍历
                seen[i] = true;
                nums[position] = cands[i];
                int amount = 0;
                for (int j = 0; j < position; j++)
                    if (nums[j] < cands[i]) amount++;
                for (int j = position + 1; j < n; j++)
                    if (cands[i] < nums[j]) amount++;
                dfs(pos, index + 1, count, base + amount, k, n);
                // 还原现场
                nums[position] = 0;
                seen[i] = false;
            }
        }
    }
}

WY18统计回文

描述

“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。花花非常喜欢这种拥有对称美的回文串,生日的时候她得到两个礼物分别是字符串A和字符串B。现在她非常好奇有没有办法将字符串B插入字符串A使产生的字符串是一个回文串。你接受花花的请求,帮助她寻找有多少种插入办法可以使新串是一个回文串。如果字符串B插入的位置不同就考虑为不一样的办法。
例如:
A = “aba”,B = “b”。这里有4种把B插入A的办法:

  • 在A的第一个字母之前: “baba” 不是回文

  • 在第一个字母‘a’之后: “abba” 是回文

  • 在字母‘b’之后: “abba” 是回文

  • 在第二个字母’a’之后 “abab” 不是回文

    所以满足条件的答案为2

输入描述:

每组输入数据共两行。 第一行为字符串A 第二行为字符串B 字符串长度均小于100且只包含小写字母

输出描述:

输出一个数字,表示把字符串B插入字符串A之后构成一个回文串的方法数

示例1

输入:

aba

b

输出:

2

import java.util.Scanner;
/*
将字符串插入到可以插入的位置,然后判断是否构成回文
*/
public class Main {
    public static void main(String[] agrs) {
        Scanner sc = new Scanner(System.in);
        String strA = sc.nextLine();
        String strB = sc.nextLine();
        
        int count = 0;  // 记录插入后符合回文的数量
        for (int i = 0;i <= strA.length(); i++) {
            // 创建一个可变字符类型,用于字符串插入
            StringBuilder temp = new StringBuilder(strA);  
            temp.insert(i, strB);  // 将strB字符串插入到指定位置
            if (isLM(temp)) {
                count++;
            }
        }
        System.out.print(count);
    }
    
    /*
    传入一个字符串,如果是回文就返回true,不是返回false
    */
    public static boolean isLM(StringBuilder str) {
        for (int i = 0, j = str.length() - 1;i < j; i++, j--) {
            if (str.charAt(i) != str.charAt(j)) {  // 双指针指向判断是否符合
                return false;
            }
        }
        return true;
    }
}

WY32买苹果

描述

小易去附近的商店买苹果,奸诈的商贩使用了捆绑交易,只提供6个每袋和8个每袋的包装(包装不可拆分)。 可是小易现在只想购买恰好n个苹果,小易想购买尽量少的袋数方便携带。如果不能购买恰好n个苹果,小易将不会购买。

输入描述:

输入一个整数n,表示小易想购买n(1 ≤ n ≤ 100)个苹果

输出描述:

输出一个整数表示最少需要购买的袋数,如果不能买恰好n个苹果则输出-1

示例1

输入:

20

输出:

3

import java.util.Scanner;
/*
1、先排除小于6个的、为奇数个的和刚好是10个的
2、因为想购买最少袋,故此先试着全部购买8袋
3、上诉两个都排除的话,就必然是大于12的偶数,
   这时对8进行除法,余数可能有2,4,6这三种情况,
   需要向够8个的取2个(这时8就变成6,但是代数没有变)来筹齐6个。
*/
public class Main {
    public static void main(String[] agrs) {
        Scanner sc = new Scanner(System.in);
        int count = sc.nextInt();
        
        // 排除小于6个的、为奇数个的和刚好是10个的
        if (count < 6 || count % 2 == 1 || count == 10) {
            System.out.print(-1);
        }else if (count % 8 == 0) {  // 先试着全部购买8袋
            System.out.print(count / 8);
        }else {
            System.out.print((count / 8) + 1);
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小沐_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值