牛客网模拟测试20180731(log函数、回想下全排列,整数+字符串的输入)

1、`给出一个含有n个数字的序列a1,a2,a3,…an,可以进行以下操作:
一次操作定义为对这个序列的每个数字进行以下两种改变之一:
1.ai ÷ 2
2.ai × 3
每一次的操作中,必须保证至少有一个数字是第1种改变;并且经过每次操作后,每一个数字都必须是整数。

牛牛得知,每进行一次操作,他就可以得到一颗西瓜糖,但是由于孱弱的数学功底,他不知道何时该对某一个数字进行第一种还是第二种改变,这使得他十分纠结,于是他找来了睿智的你,希望你帮他计算出,他最多可以得到多少颗西瓜糖。`

我的答案(AC):

import java.util.ArrayList;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        ArrayList<Integer> list = new ArrayList<>();
        while(sc.hasNextInt()){
            list.add(sc.nextInt());
        }
        getNumFunction(list);
        System.out.println(num);
    }

    static int num = 0;
    private static void getNumFunction(ArrayList<Integer> list) {
        if(isEnd(list)){
            return ;
        }
        //只对一个偶数/2,其余的都*3
        int i = 0;
        for(;i<list.size();i++){
            if(list.get(i) % 2 == 0){
               list.set(i,list.get(i)/2);
               break;
            }else{
                list.set(i,list.get(i) * 3);
            }
        }
        i++;
        for(;i<list.size();i++){
            list.set(i,list.get(i) * 3);
        }
        num++;
        getNumFunction(list);
    }

    private static boolean isEnd(ArrayList<Integer> list) {
        boolean flag = true;
        for(int i=0;i<list.size();i++){
            if(list.get(i) % 2 == 0){
                flag = false;
                break;
            }
        }
        return flag;
    }
}

当都是奇数的时候结束,只让一个偶数除以2,其他乘3,然后递归。次数最多。

别人的答案:所有2的因子数量之和即为答案。

import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner input=new Scanner(System.in);
        while(input.hasNext()){
            int n=input.nextInt();
            int[] a=new int[n];
            int count=0;
            for(int i=0; i<n; i++){
                a[i]=input.nextInt();
                if(a[i]%2==0){//如果这个数是偶数
                    while(a[i]%2==0){//看能够除几次
                        a[i]/=2;
                        count++;
                    }
                }
            }
            System.out.println(count);
        }
    }
}

很巧妙,没想出来,我的做法复杂了。

2、

牛牛很喜欢对数字进行比较,但是对于3 > 2这种非常睿智的比较不感兴趣。上了高中之后,学习了数字的幂,他十分喜欢这种数字表示方法,比如xy。
由此,他想出了一种十分奇妙的数字比较方法,给出两个数字x和y,请你比较xy和yx的大小,如果前者大于后者,输出">",小于则输出"<",等于则输出"="。

我的答案(AC):用log10

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int x = sc.nextInt();
        int y = sc.nextInt();
        double xx = y * Math.log10(x);
        double yy = x * Math.log10(y);
        if(xx > yy)
            System.out.println(">");
        else if(xx < yy){
            System.out.println("<");
        }else
            System.out.println("=");

    }
}

补充:java的log函数==》
(1)Sun的J2SE提供了一个单一的Java对数方法——double java.lang.Math.log(double),这很轻易使用double x = Math.log(5);价于:x = ln 5 或 x = loge5,即以e为底的自然对数。
(2)还没有办法计算以10为底或以2为底的对数。但是它们却是在计算Java对数时用的最多的。要想解决这个问题,需要使用数学和对数方程: logx(y) =loge(y) / loge(x),换底公式

3、`一般的括号匹配问题是这样的:

给出一个字符串,判断这个括号匹配是不是合法的括号匹配。

如”((” 和 “())”都不是合法的括号匹配,但是”()()()”,”(()())()”等就是合法的括号匹配。

这个问题解决起来非常简单,相信大家都知道怎么解决。

现在给出一个加强版的括号匹配问题: 给出n个由括号 ‘(’ 和 ‘)’ 组成的字符串,请计算出这些字符串中有多少对字符串满足si + sj是合法的括号匹配。如果si + sj和sj + si都是合法的括号匹配(i ≠ j),那么这两种搭配都需要计入答案;如果对于si,si + si是合法的括号匹配,那么也需要计入答案。`

我的答案(80% 复杂度过高):

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        sc.nextLine();
        String[] arr = new String[n];
        int i = 0;
        while(sc.hasNextLine()){
            arr[i] = sc.nextLine();
            i++;
        }
        int num = 0;
        for(int p=0;p<n;p++){
            for(int q=p;q<n;q++){
                if(p == q){
                    String str = arr[p];
                    if(isValid(str))
                        num++;
                }else {
                    String s1 = arr[p];
                    String s2 = arr[q];
                    String str = s1 + s2;
                    if(isValid(str))
                        num++;
                    str = s2 + s1;
                    if(isValid(str))
                        num++;
                }
            }
        }
        System.out.println(num);
    }

    private static boolean isValid(String str) {
        int len = str.length();
        int count = 0;
        for(int i=0;i<len;i++){
            if(str.charAt(i) == '('){
                count++;
            }else{
                count--;
                if(count < 0)
                    return false;
            }
        }
        if (count == 0)
            return true;
        else
            return false;
    }
}

优化:
链接:https://www.nowcoder.com/questionTerminal/98d6fa0bd6184b03a503febcee1b1082
来源:牛客网

(1)合法判断:去除字符串中形如”()”,直到不能去除为止,若字符串被清理为空,那么字符串合法,否则字符串不合法,变成以下三种:”(…(“、”)…)”、”)…)(…(“。考虑清理之后的字符串;
(2)n个字符串中,合法的字符串有num1个,不合法的字符串中,只有”(…(“、”)…)”能配成一组,二重循环遍历不合法字符串,配对数为num2;
(3)最终结果为num1*num1+num2。
别人的答案:

链接:https://www.nowcoder.com/questionTerminal/98d6fa0bd6184b03a503febcee1b1082
来源:牛客网

#include<iostream>
#include<string>
#include<vector>
using namespace std;
string clean(string s){
 while(s.find("()")!=-1)
     s.erase(s.find("()"), 2);
 return s;
}
int main(){
 ios::sync_with_stdio(false);
 int n;
 cin >> n;
 vector<string> str(n, "");
 string temp;
 int num1=0;
 vector<int> pool;
 for(int i=0;i<n;i++){
     cin >> temp;
     str[i] = clean(temp);
     if(str[i].length()==0)
         num1++;
     else if(str[i][0]=='(')
         pool.push_back(str[i].length());
     else if(str[i][0]==')' && str[i].find('(')==-1)
         pool.push_back(-str[i].length());
 }
 int num2=0;
 for(int i=0;i<(int)pool.size();i++)
     for(int j=i;j<(int)pool.size();j++)
         if(pool[i]+pool[j]==0)
             num2++;
 cout<<num1*num1+num2<<endl;
}

注:不匹配的部分只有这几种情况:全是左括号;全是右括号;先是部分右括号,然后左括号。这三种里面只有前两种在个数相同时,组合起来可以合法。
但,为什么是num1*num1呢???
4、`有一个长度为N的序列。一开始,这个序列是1, 2, 3,… n - 1, n的一个排列。

对这个序列,可以进行如下的操作:

每次选择序列中k个连续的数字,然后用这k个数字中最小的数字替换这k个数字中的每个数字。

我们希望进行了若干次操作后,序列中的每个数字都相等。请你找出需要操作的最少次数。`
我的答案:

import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int k = sc.nextInt();
        int[] arr = new int[n];
        int i = 0;
        while(sc.hasNext()){
            arr[i] = sc.nextInt();
            i++;
        }
        int count = 0;
        Arrays.sort(arr);
        int j=0;
        for(;j<n-k;j=j+k-1){
            int tmp = arr[j];
            for(int t=j;t<j+k;t++){
                arr[t] = tmp;//其实不用存,这里直接输出就可以sout,这种考试需要输出
            }
            count++;
        }
        int tmp = arr[n-k];
        for(j=n-k;j<n;j++){
            arr[j] = tmp;
        }
        count++;
        System.out.println(count);
    }
}

先排序,然后k个进行遍历,把k个数都变为k个中的第一个;最后处理最后k个。

别人的答案:

链接:https://www.nowcoder.com/questionTerminal/9afc528ca8f14511832b9a537977ecf5
来源:牛客网

import java.util.Scanner;
public class Main {  public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        int k = scan.nextInt();
        int count = 1;
        Integer[] num = new Integer[n];
        for(int i = 0; i < n;i++)  num[i] = scan.nextInt();
        int len = num.length;
        while(len > k) {  len -= (k - 1);  count += 1;
        }

        System.out.println(count);

    }
}

可以只count++,没要必要没得求最小值,因为人家只问了次数。

5、牛牛很喜欢玩接龙游戏,一天他突发奇想,发明了一种叫做“字符串链”的游戏。 这个游戏的规则是这样的,给出3个字符串A,B,C,如果它们满足以下两个条件,那么就可以构成一个“字符串链”:
1.A的最后一个字母和B的第一个字母相同;
2.B的最后一个字母和C的第一个字母相同。
现在牛牛给出了3个字符串A,B,C,希望你能判断这3个字符串能否构成一个“字符串链”,若能则输出“YES”,否则输出“NO”。

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String string = sc.nextLine();
        String[] strs = string.split(" ");
        char aLast = strs[0].charAt(strs[0].length()-1);
        char bFirst = strs[1].charAt(0);
        char bLast = strs[1].charAt(strs[1].length()-1);
        char cFirst = strs[2].charAt(0);
        if(aLast == bFirst && bLast == cFirst)
            System.out.println("YES");
        else
            System.out.println("NO");

    }
}

这个不想说啥。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值