1.题目描述
有一个整数n,将n分解成若干个不同自然数之和,问如何分解能使这些数的乘积最大,输出这个乘积m。
输入:一个整数
输出:
一个整数
样例输入:
15
样例输出:
144
解题思路:
要求乘积最大,就得让每一个数尽量地接近,从2,开始分,最后剩下的数依次从后面加到前面的数上面(每个数加上1)。例如10,分开后是2,3,4,剩下1,加到最后面的4上变成2,3,5。如果是18,依次是2,3,4,5,剩下4,依次加到前面的数上是3,4,5,6。
代码如下:
import java.math.BigInteger; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scc=new Scanner(System.in); int n = scc.nextInt(); String result = solve(n); System.out.println(result); } public static String solve(int num){ BigInteger big1=new BigInteger("1"); int a[]=new int[3000]; int n = num; int sum=2; a[0]=2; int i=1; int j=0; while(true){ a[i]=a[i-1]+1; if(sum+a[i]>n){ break; }else{ sum+=a[i]; } i++; } a[i]=n-sum; //剩余的数 j=i-1; // System.out.println(a[i]); int mm = a[i]/(j+1); int nn = a[i]%(j+1); for(int x=0;x<i;x++){ a[x]+=mm; } for(int y=0;y<nn;y++){ a[j]++; j--; } for(int k=0;k<i;k++){ // System.out.print(a[k]+" "); big1=big1.multiply(BigInteger.valueOf(a[k])); } return big1.toString(); } }
2.题目描述
拼图,是一个老少皆宜的益智游戏,在打乱的3*3的范围中,玩家只能每次将空格(0)和相邻的数字格(上、下、左、右)交换,最终调整出一个完整的拼图。
完整拼图为:
1 2 3
4 5 6
7 8 0
输入:测试数据共3行,每行3个数字 ,包括数字0、1、2、3.....8(无重复)
输出:
还原完整拼图的最少移动次数。如不需要调整,则输出0;如无解,则输出-1。
例如:
0 1 3
4 2 5
7 8 6
依次移动1,2,5,6,即可还原为正确拼图,移动次数为4
样例输入:
0 1 3
4 2 5
7 8 6
样例输出:
4
解题思路:
广度优先搜索
代码如下:
import java.io.*; import java.util.*; import java.text.*; import java.math.*; import java.util.regex.*; import java.util.Scanner; import java.util.Set; import java.util.HashSet; import java.util.ArrayList; import java.lang.StringBuilder; public class Main{ public static String destNumbers = "123456780"; public static Set<Integer> set = new HashSet<Integer>(); public static int[]moveTable = new int[]{12,14,10,13,15,11,5,7,3}; public static ArrayList<Node> getNextMoveList(Node pNode){ int position = pNode.numbers.indexOf("0"); int moveStatus = moveTable[position]; ArrayList<Node> cNodes = new ArrayList<Node>(); for(int status=1; status <=8; status=status<<1){ if((moveStatus & status) > 0){ char[] charNumbers = pNode.numbers.toCharArray(); int switchPosition = 0; if(status == 1){ switchPosition = position - 3; } else if(status == 2){ switchPosition = position - 1; } else if(status == 4){ switchPosition = position + 1; } else if(status == 8){ switchPosition = position + 3; } charNumbers[position] = charNumbers[switchPosition]; charNumbers[switchPosition] = '0'; String s = String.valueOf(charNumbers); if(!set.contains(Integer.valueOf(s))){ set.add(Integer.valueOf(s)); Node n = new Node(pNode, s, charNumbers[position]); cNodes.add(n); } } } return cNodes; } static int getResult(Node node){ String result = ""; while(node.parentNode != null){ result += node.currentNum; node = node.parentNode; } return new StringBuffer(result).reverse().toString().length(); } static int run(String numbers){ if(numbers.equals(destNumbers)){ return 0; } ArrayList<Node> numsList = new ArrayList<Node>(); numsList.add(new Node(null, numbers, ' ')); while(numsList.size() > 0){ ArrayList<Node> tmpList = new ArrayList<Node>(); for(Node pNode : numsList){ ArrayList<Node> cNodes = getNextMoveList(pNode); for(Node cNode : cNodes){ if(cNode.numbers.equals(destNumbers)){ return getResult(cNode); } tmpList.add(cNode); } } numsList = tmpList; } return -1; } public static void main(String[] args) { Scanner scan = new Scanner(System.in); String numbers = new String(); for(int rows=3; rows>0; rows--){ for(String n: scan.nextLine().split(" ")){ numbers += n; } } int res = run(numbers); System.out.println(String.valueOf(res)); } } class Node { public Node(Node parentNode, String numbers, char currentNum){ this.numbers = numbers; this.currentNum = currentNum; this.parentNode = parentNode; } public char currentNum; public String numbers; public Node parentNode; }
3.题目描述
一个一维数组,记录n天中每天的携程股价。
股市交易规则如下:
a)一天只能有买进或者卖出一种操作,也可以不做任何操作,卖出时价格减买入时价格即为收益
b)每次卖出操作后有冻结期,k天之后才能进行下一次买进操作(k>=1)
c)买进之后必须卖出才能再次买进
设计一个算法,找到交易收益最大化的买进卖出策略,返回最后的最大收益值
输入:
一维正整数数组,表示每天股价 (一维正整数数组,表示每天股价)
输出:
返回最大收益
样例输入:
int[] sotckPrice = {1,2,3,5,2,6,3,7};
int k = 2;
输入为
8(表示数组长度)
1(开始依次输入数组元素)
2
3
5
2
6
3
7
2(输入k)
样例输出:
8 (1买进,5卖出,3买进,7卖出,收益最大为8)
解题思路:
扫描序列,按照题意判断冷却时间,然后更新答案
代码如下:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while(scanner.hasNext()){
int n = scanner.nextInt();
int stockPrice[] = new int[n+1];
for(int i=1;i<=n;i++){
stockPrice[i] = scanner.nextInt();
}
int k = scanner.nextInt();
System.out.println(getMaxProfit(n, stockPrice, k));
}
scanner.close();
}
private static int getMaxProfit(int n,int stockPrice[],int k) {
int cur=-1000000000, ans=0;
int dp[] = new int[n+1];
for(int i=1;i<=n;i++){
dp[i] = Math.max(stockPrice[i]+cur, dp[i-1]);
if(i>=k){
cur = Math.max(cur, dp[i-k]-stockPrice[i]);
}else{
cur = Math.max(cur, -stockPrice[i]);
}
ans = Math.max(ans, dp[i]);
}
return ans;
}
}
