1.第一题是numberofprize(),意思是a,b,c三个数, 2个a可以转b或c, a和 b也可以转 c,a,b换一个礼物,问最多转多少礼物
public static int numberofprize (int a, int b, int c) {
// write code here
List list = new ArrayList<>();
list.add(a);
list.add(b);
list.add©;
Collections.sort(list);
int max = list.get(2);
int med = list.get(1);
int min = list.get(0);
if(max - med >= (med - min) 2){
max -= 2 * (med - min);
int temp = Math.max((max - med) / 5,0);
return temp + med;
}else{
min = (max - med) / 2 + min;
return (min + med) / 2;
}
}
2.盖房子,给房子位置和宽度问多少种方法
public static int getHouses(int t, int[] xa) {
// write code here
int n = 0;
if (xa == null || xa.length == 0) return n;
for (int i = 0; i < xa.length-2; i += 2){
int dis1 = xa[i+2] - xa[i];
double dis2 = dis1 - 0.5(xa[i+3] + xa[i+1]);
if (dis2 > (double) t) n += 2;
if (dis2 == (double) t) n++;
}
return n+2;
}
3.构造密码什么的,给初始密码,自己从0-9写第一个数字,然后这个数字和初始密码第2个求平均值,可以向上或者向下取值,问最后多少种(不包括初始密码)
public class Solution {
static boolean flag;
public static long dfs(String password,String cur,int num,int d,int n){
cur+=num;
if(d==n){
if(cur.equals(password)) flag = true;
return 1;
}
int curNum = password.charAt(d)-‘0’;
int sum = curNum+num;
if((sum&1)==0){
return dfs(password,cur,sum/2,d+1,n);
}else{
return dfs(password,cur,sum/2,d+1,n) + dfs(password,cur,sum/2+1,d+1,n);
}
}
public static long getPasswordCount1(String password){
long res = 0;
flag = false;
for(int i=0;i<10;i++){
res+=dfs(password,"",i,1,password.length());
}
return flag?res-1:res;
}
}
-
记忆化搜索
public class Solution {
static long[][] dp;
//记忆化搜索
public static long dfs(String password,int num,int d,int n){
if(d==n) return 1;
if(dp[d][num]!=0) return dp[d][num];
int curNum = password.charAt(d)-‘0’;
int sum = curNum+num;
if((sum&1)==0){
return dp[d][num] = dfs(password,sum/2,d+1,n);
}else{
return dp[d][num] = dfs(password,sum/2,d+1,n) + dfs(password,sum/2+1,d+1,n);
}
}
public static long getPasswordCount(String password){
dp = new long[password.length()][10];
long res = 0;
for(int i=0;i<10;i++){
res+=dfs(password,i,1,password.length());
}
// 只有相邻两位相差<=1才有可能生成和初始串相同的串,否则不可能
for(int i=1;i<password.length();i++){
// 差>1,直接返回res
if(Math.abs(password.charAt(i)-password.charAt(i-1))>1) return res;
}
// 说明存在重复
return res-1;
}
} -
验证程序,随机生成数字字符串,两者输出结果全部相同说明正确
import java.util.Random;
public class mima {
static long[][] dp;
//记忆化搜索
public static long dfs(String password,int num,int d,int n){
if(d==n) return 1;
if(dp[d][num]!=0) return dp[d][num];
int curNum = password.charAt(d)-‘0’;
int sum = curNum+num;
if((sum&1)0){
return dp[d][num] = dfs(password,sum/2,d+1,n);
}else{
return dp[d][num] = dfs(password,sum/2,d+1,n) + dfs(password,sum/2+1,d+1,n);
}
}
public static long getPasswordCount(String password){
dp = new long[password.length()][10];
long res = 0;
for(int i=0;i<10;i++){
res+=dfs(password,i,1,password.length());
}
// 只有相邻两位相差<=1才有可能生成和初始串相同的串,否则不可能
for(int i=1;i<password.length();i++){
// 差>1,直接返回res
if(Math.abs(password.charAt(i)-password.charAt(i-1))>1) return res;
}
// 说明存在重复
return res-1;
}
// 暴力dfs
public static long dfs1(String password,int num,int d,int n){
if(dn) return 1;
int curNum = password.charAt(d)-‘0’;
int sum = curNum+num;
if((sum&1)==0){
return dfs1(password,sum/2,d+1,n);
}else{
return dfs1(password,sum/2,d+1,n) + dfs1(password,sum/2+1,d+1,n);
}
}
public static long getPasswordCount1(String password){
long res = 0;
for(int i=0;i<10;i++){
res+=dfs1(password,i,1,password.length());
}
// 只有相邻两位相差<=1才有可能生成和初始串相同的串,否则不可能
for(int i=1;i<password.length();i++){
// 差>1,直接返回res
if(Math.abs(password.charAt(i)-password.charAt(i-1))>1) return res;
}
// 说明存在重复
return res-1;
}
public static void main(String[] args) {
Random r = new Random(1);
int len = 10;
String[] passwordList = new String[len];
for(int i=0;i<len;i++){
StringBuilder password = new StringBuilder();
for(int j=0;j<30;j++){
password.append(Math.abs(r.nextInt())%10);
}
passwordList[i] = password.toString();
}
long[] res1 = new long[len];
long[] res2 = new long[len];
long start1 = System.currentTimeMillis();
for(int i=0;i<len;i++){
res1[i] = getPasswordCount(passwordList[i]);
}
long end1 = System.currentTimeMillis();
System.out.println(“记忆化搜索运行时间为:”+(end1-start1)+“ms”);
for(int i=0;i<len;i++){
res2[i] = getPasswordCount1(passwordList[i]);
}
System.out.println(“暴力运行时间为:”+(System.currentTimeMillis()-end1)+“ms”);
boolean isSame = true;
for(int i=0;i<len;i++){
if(res1[i]!=res2[i]){
System.out.println(“数据:” + passwordList[i] + “两者结果不一致”);
isSame = false;
}
}
if(isSame) System.out.println(“结果一致”);
}
}