牛客網模擬測試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");

    }
}

這個不想說啥。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章