LeetCode1744 / 牛客:万万没想到之聪明的编辑(体验ACM模式)
Posted Zephyr丶J
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode1744 / 牛客:万万没想到之聪明的编辑(体验ACM模式)相关的知识,希望对你有一定的参考价值。
1744. 你能在你最喜欢的那天吃到你最喜欢的糖果吗?
2021.6.1 每日一题,也祝大家节日快乐啊
题目描述
给你一个下标从 0 开始的正整数数组 candiesCount ,其中 candiesCount[i] 表示你拥有的第 i 类糖果的数目。同时给你一个二维数组 queries ,其中 queries[i] = [favoriteTypei, favoriteDayi, dailyCapi] 。
你按照如下规则进行一场游戏:
你从第 0 天开始吃糖果。
你在吃完 所有 第 i - 1 类糖果之前,不能 吃任何一颗第 i 类糖果。
在吃完所有糖果之前,你必须每天 至少 吃 一颗 糖果。
请你构建一个布尔型数组 answer ,满足 answer.length == queries.length 。answer[i] 为 true 的条件是:在每天吃 不超过 dailyCapi 颗糖果的前提下,你可以在第 favoriteDayi 天吃到第 favoriteTypei 类糖果;否则 answer[i] 为 false 。注意,只要满足上面 3 条规则中的第二条规则,你就可以在同一天吃不同类型的糖果。
请你返回得到的数组 answer 。
示例 1:
输入:candiesCount = [7,4,5,3,8], queries = [[0,2,2],[4,2,4],[2,13,1000000000]]
输出:[true,false,true]
提示:
1- 在第 0 天吃 2 颗糖果(类型 0),第 1 天吃 2 颗糖果(类型 0),第 2 天你可以吃到类型 0 的糖果。
2- 每天你最多吃 4 颗糖果。即使第 0 天吃 4 颗糖果(类型 0),第 1 天吃 4 颗糖果(类型 0 和类型 1),你也没办法在第 2 天吃到类型 4 的糖果。换言之,你没法在每天吃 4 颗糖果的限制下在第 2 天吃到第 4 类糖果。
3- 如果你每天吃 1 颗糖果,你可以在第 13 天吃到类型 2 的糖果。
示例 2:
输入:candiesCount = [5,2,6,4,1], queries = [[3,1,2],[4,10,3],[3,10,100],[4,100,30],[1,3,1]]
输出:[false,true,true,false,false]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/can-you-eat-your-favorite-candy-on-your-favorite-day
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
简单的前缀和预处理
然后对于每个查询,进行数学的范围判断
需要特别注意的是,数据的范围,和第0天也算一天!!!
class Solution {
public boolean[] canEat(int[] candiesCount, int[][] queries) {
//前缀和
int l = candiesCount.length;
long[] pre = new long[l + 1];
for(int i = 1; i <= l; i++){
pre[i] = pre[i - 1] + candiesCount[i - 1];
}
int n = queries.length;
boolean[] res = new boolean[n];
for(int i = 0; i < n; i++){
int type = queries[i][0];
long day = queries[i][1];
long cap = queries[i][2];
//两个条件,之前所有糖果要在day天吃完,加上本类的糖果要每天吃一个最少
if(pre[type] < cap * (day + 1) && pre[type + 1] >= (day + 1))
res[i] = true;
}
return res;
}
}
万万没想到之聪明的编辑
题目描述
链接:https://www.nowcoder.com/questionTerminal/42852fd7045c442192fa89404ab42e92
来源:牛客网
我叫王大锤,是一家出版社的编辑。我负责校对投稿来的英文稿件,这份工作非常烦人,因为每天都要去修正无数的拼写错误。但是,优秀的人总能在平凡的工作中发现真理。我发现一个发现拼写错误的捷径:
1. 三个同样的字母连在一起,一定是拼写错误,去掉一个的就好啦:比如 helllo -> hello
2. 两对一样的字母(AABB型)连在一起,一定是拼写错误,去掉第二对的一个字母就好啦:比如 helloo -> hello
3. 上面的规则优先“从左到右”匹配,即如果是AABBCC,虽然AABB和BBCC都是错误拼写,应该优先考虑修复AABB,结果为AABCC
我特喵是个天才!我在蓝翔学过挖掘机和程序设计,按照这个原理写了一个自动校对器,工作效率从此起飞。用不了多久,我就会出任CEO,当上董事长,迎娶白富美,走上人生巅峰,想想都有点小激动呢!
……
万万没想到,我被开除了,临走时老板对我说: “做人做事要兢兢业业、勤勤恳恳、本本分分,人要是行,干一行行一行。一行行行行行;要是不行,干一行不行一行,一行不行行行不行。” 我现在整个人红红火火恍恍惚惚的……
请听题:请实现大锤的自动校对程序
输入描述:
第一行包括一个数字N,表示本次用例包括多少个待校验的字符串。
后面跟随N行,每行为一个待校验的字符串。
输出描述:
N行,每行包括一个被修复后的字符串。
示例1
输入
2
helloo
wooooooow
输出
hello
woow
思路
主要是练ACM模式,结果做的第一道题就练住了,用例没问题,就是输入有问题,我还不知道问题出在哪里…我写的,我感觉没问题啊
每次输入的时候都会在输入数字后面多一个空格,不知道啥原因
import java.util.Scanner;
import java.util.Arrays;
public class Main{
public static void main(String[] args){
Main main = new Main();
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); //输入n
String[] ss = new String[n];
for(int i = 0; i < n; i++){
ss[i] = sc.nextLine();
}
for(int i = 0; i < n; i++){
String s = main.ck(ss[i]);
System.out.println(s);
}
}
public String ck(String s){
int l = s.length();
if(l < 2)
return s;
char[] cc = s.toCharArray();
//先检查3个的,再检查aabb的
for(int i = 2; i < l; i++){
if(cc[i - 1] == cc[i] && cc[i - 2] == cc[i])
cc[i - 2] = ' ';
}
int index = 0;
for(int i = 0; i < l; i++){
if(cc[i] != ' ')
cc[index++] = cc[i];
}
for(int i = 3; i < index; i++){
if(cc[i - 3] == cc[i - 2] && cc[i - 1] == cc[i]){
cc[i - 1] = ' ';
i = i + 2;
}
}
int id = 0;
for(int i = 0; i < index; i++){
if(cc[i] != ' ')
cc[id++] = cc[i];
}
cc = Arrays.copyOfRange(cc, 0, id);
return new String(cc);
}
}
看了大家写的题解,输入字符串都是用的next,然后我改成next,过了
看到一个题解里在输入数字后写了一句话 “数字后面的换行,要记得去掉这个干扰。”
他是在输入数字后面又写了一句nextLine(),才进行后面的输入的,我试了一下,这样也可以
改后的代码:
import java.util.Scanner;
import java.util.Arrays;
public class Main{
public static void main(String[] args){
Main main = new Main();
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); //输入n
// 数字后面的换行,要记得去掉这个干扰。
sc.nextLine();
//或者不加上面这句话,把下面输入改成next
String[] ss = new String[n];
for(int i = 0; i < n; i++){
ss[i] = sc.nextLine();
}
for(int i = 0; i < n; i++){
String s = main.ck(ss[i]);
System.out.println(s);
}
}
public String ck(String s){
int l = s.length();
if(l < 2)
return s;
char[] cc = s.toCharArray();
//先检查3个的,再检查aabb的
for(int i = 2; i < l; i++){
if(cc[i - 1] == cc[i] && cc[i - 2] == cc[i])
cc[i - 2] = ' ';
}
int index = 0;
for(int i = 0; i < l; i++){
if(cc[i] != ' ')
cc[index++] = cc[i];
}
for(int i = 3; i < index; i++){
if(cc[i - 3] == cc[i - 2] && cc[i - 1] == cc[i]){
cc[i - 1] = ' ';
i = i + 2;
}
}
int id = 0;
for(int i = 0; i < index; i++){
if(cc[i] != ' ')
cc[id++] = cc[i];
}
cc = Arrays.copyOfRange(cc, 0, id);
return new String(cc);
}
}
今天第一道这种ACM的题,输入很成问题,另外还需要自己导入包,因此还得记住常用的包名
还有类名要写成Main,修饰符是public,方法可以写成静态的,然后就不用创建main对象了
另外,看一下输入的文章
//Scanner类中的方法
//优点一: 可以获取键盘输入的字符串
//优点二: 有现成的获取int,float等类型数据,非常强大,也非常方便;
public static void ScannerTest(){
Scanner sc = new Scanner(System.in);
System.out.println("ScannerTest, Please Enter Name:");
String name = sc.nextLine(); //读取字符串型输入
System.out.println("ScannerTest, Please Enter Age:");
int age = sc.nextInt(); //读取整型输入
System.out.println("ScannerTest, Please Enter Salary:");
float salary = sc.nextFloat(); //读取float型输入
System.out.println("Your Information is as below:");
System.out.println("Name:" + name +"\\n" + "Age:"+age + "\\n"+"Salary:"+salary);
}
Scanner是Java5的新特征,主要功能是简化文本扫描。Scanner的中文意思就是扫描仪,也就是将一份数据从一个地方扫描并显示到另外一个地方。一个可以使用正则表达式来解析基本类型和字符串的简单文本扫描器。
Scanner使用分隔符模式将其输入分解为标记,默认情况下该分隔符模式与空白匹配。然后可以使用不同的 next 方法将得到的标记转换为不同类型的值。当通过new Scanner(System.in)创建一个Scanner,控制台会一直等待输入,直到敲回车键结束,把所输入的内容传给Scanner,作为扫描对象。而且Scanner类有一个假设,在输入结束时会抛出IOException,而Scanner类会把这个异常吞掉。
经常有人说使用Scanner的原因是因为它使用简便,不如说Scanner的构造器支持多种方式,构建Scanner的对象很方便。可以从字符串(Readable)、输入流、文件等等来直接构建Scanner对象,有了Scanner了,就可以逐段(根据正则分隔式)来扫描整个文本,并对扫描后的结果做想要的处理。
scanner好比一个带游标或者指针的扫描仪,调用其hasNextLine()好比将游标向前探索直到遇到一个换行符,如果这个过程中遇到字符串对象则返回true并且游标复位。调用其nextLine()方法其实就是游标向前探索直到遇到一个换行符,此时并不复位,而是游标直接定位到目标数据的下一行,并返回探索过程中检测到的数据包括空格。
java里常使用的方法next() 与 nextLine() 区别
next():
1、一定要读取到有效字符后才可以结束输入。
2、对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。
3、只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。
next() 不能得到带有空格的字符串。
nextLine():
1、以Enter为结束符,也就是说 nextLine()方法返回的是输入回车之前的所有字符。
2、可以获得空白。import java.io.BufferedReader;
另外,一些情况下用IO流输入
// InputStreamReader和BufferedReader方法
// 优点: 可以获取键盘输入的字符串
// 缺点: 如何要获取的是int,float等类型的仍然需要转换
public static void ReadTest(){
System.out.println("ReadTest, Please Enter Data:");
InputStreamReader is = new InputStreamReader(System.in); //new构造InputStreamReader对象
BufferedReader br = new BufferedReader(is); //拿构造的方法传到BufferedReader中,此时获取到的就是整个缓存流
try{ //该方法中有个IOExcepiton需要捕获
String name = br.readLine();
System.out.println("ReadTest Output:" + name);
}
catch(IOException e){
e.printStackTrace();
}
}
具体看文章:https://blog.csdn.net/idomyway/article/details/82748000
以上是关于LeetCode1744 / 牛客:万万没想到之聪明的编辑(体验ACM模式)的主要内容,如果未能解决你的问题,请参考以下文章
[LeetCode] 1744. 你能在你最喜欢的那天吃到你最喜欢的糖果吗?
LeetCode 1744 你能在你最喜欢的那天吃到你最喜欢的糖果吗?[前缀和] HERODING的LeetCode之路