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");
}
}
這個不想說啥。