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");
}
}
这个不想说啥。