热身题
public class Main { public static void main(String[] args) { for(int i = 10; i < 100; i += 2){ System.out.println("本页包括 : " + i + " 和 " + (i + 1)); } } }
我把它看成是一道考二叉树的题. 考的是第k层的结点个数, 但是最后要加1, 这个1可以理解成头结点. 拿张纸条切一切和二叉树的图对比一下即可.
public class Main { public static void main(String[] args) { System.out.println(getNoodles(10)); } public static int getNoodles(int n){ return (1 << n) + 1; } }
我的思路是先拼接出字符串, 然后通过数组原地调整的方式不断缩字符串, 类似2013年第八题幸运数.
public class Main { public static void main(String[] args) { String s = ""; for(int i = 0; i < 106; i++){ s += "abcdefghijklmnopqrs"; } char[] arr = s.toCharArray(); int len = arr.length; int index = 0; while(len != 1){ for(int i = 0; i < len; i++){ if(((i + 1) & 1) == 0){ arr[index++] = arr[i]; } } System.out.println(arr[0]);//把缩完后每一次的开头都打印出来, 以便检验. index = 0; len = len / 2; } } }
for(int i=1; i<100; i++) { if(________________) //填空 System.out.println(i*i/2); else System.out.println((i*i-1)/2); }
判断一个数是不是偶数
double x = 111; for(int n = 10000; n>=0; n--){ int i = 2 * n + 1; x = 2 + (i*i / x); } System.out.println(String.format("%.4f", ______________));
根据题目中的代码可以推算出x等于2+一大坨分数, 然后即可通过解方程得到圆周率.
解题思路: 按照题目的步骤判断两个结果是否相等, 两个结果分别用4个变量凑出, 注意判断相等的时候使用浮点类型.
public class Main { public static void main(String[] args) { int res = 0; float num1 = 0; float num2 = 0; for(float a = 1; a <= 9; a++){ for(float b = 1; b <= 9; b++){ if(b == a) continue; for(float c = 1; c <= 9; c++){ for(float d = 1; d <= 9; d++){ if(c == d) continue; num1 = (a * 10 + c) / (b * 10 + d); num2 = (a * c) / (b * d); if(num1 == num2){ res++; } } } } } System.out.println(res); } }
解题思路: 首先通过全排列找到所有的情况, 然后在所有情况中筛选符合题目要求的字符串. 最后比较符合要求的字符串的字典序, 通过比较器比较(各个语言都有).
public class Main { public static LinkedList<String> qua = new LinkedList<String>(); public static void main(String[] args) { String str = "AA223344"; process(str.toCharArray(), 0);//全排列 ArrayList<String> preList = new ArrayList<String>(); //拿到符合要求的序列 for(String s : qua){ if(isOk(s)){ preList.add(s); } } //按照字典序排序 Collections.sort(preList, new StringComparator()); System.out.println(preList.get(0)); } public static class Index{ public int first; public int last; public Index(int first){ this.first = first; } } public static boolean isOk(String s){ char[] arr = s.toCharArray(); HashMap<Character, Index> map = new HashMap<Character, T7.Index>(); for(int i = 0; i < arr.length; i++){ if(!map.containsKey(arr[i])){ map.put(arr[i], new Index(i)); }else{ Index index = map.get(arr[i]); index.last = i; map.put(arr[i], index); } } Index a = map.get('A'); if(a.last - a.first - 1 != 1){ return false; } Index b = map.get('2'); if(b.last - b.first - 1 != 2){ return false; } Index c = map.get('3'); if(c.last - c.first - 1 != 3){ return false; } Index d = map.get('4'); if(d.last - d.first - 1 != 4){ return false; } return true; } public static void process(char[] ori, int index){ if(index == ori.length){ qua.add(String.valueOf(ori)); return; } for(int i = index; i < ori.length; i++){ swap(ori, index, i); process(ori, index + 1); swap(ori, index, i); } } public static class StringComparator implements Comparator<String> { public int compare(String s1, String s2) { return s1.compareTo(s2); } } public static void swap(char[] ori, int i, int j){ char temp = ori[i]; ori[i] = ori[j]; ori[j] = temp; } }
【格式要求】 程序首先读入一个整数N(2<N<100),表示小朋友的人数。 接着是一行用空格分开的N个偶数(每个偶数不大于1000,不小于2) 要求程序输出一个整数,表示老师需要补发的糖果数。 例如:输入 3 2 2 4 程序应该输出: 4 资源约定: 峰值内存消耗(含虚拟机) < 256M CPU消耗 < 1000ms
解题思路: 按照题目一路写代码
public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int[] arr = new int[sc.nextInt()];//每个孩子有多少糖 int[] tempCandy = new int[arr.length];//定义一个辅助数组保存每个孩子给左边孩子给多少糖 for(int i = 0; i < arr.length; i++){ arr[i] = sc.nextInt(); } int left = 0; int res = 0; boolean equal = false; //只要孩子的糖不相等就进行循环 while(!equal){ //每个孩子付出糖 for(int i = 0; i < arr.length; i++){ tempCandy[i] = arr[i] / 2; arr[i] /= 2; } //每个孩子接收糖 for(int i = 0; i < arr.length; i++){ left = getLeftIndex(i, arr); arr[left] += tempCandy[i]; } //老师发糖平衡天下 for(int i = 0; i < arr.length; i++){ if((arr[i] & 1) != 0){ arr[i] += 1; res++; } } //看看这一轮平了没有 boolean isEqual = true; for(int i = 1; i < arr.length; i++){ if(arr[i] != arr[i - 1]){ isEqual = false; break; } } equal = isEqual ? true : false; } System.out.println(res); } public static int getLeftIndex(int index, int[] arr){ return index == 0 ? arr.length - 1 : index - 1; } }
数据格式】 输入一行3个整数,用空格分开:n m k (1<=n,m<=50, 1<=k<=12) 接下来有 n 行数据,每行有 m 个整数 Ci (0<=Ci<=12)代表这个格子上的宝物的价值 要求输出一个整数,表示正好取k个宝贝的行动方案数。该数字可能很大,输出它对 1000000007 取模的结果。 例如,输入: 2 2 2 1 2 2 1 程序应该输出: 2 再例如,输入: 2 3 2 1 2 3 2 1 5 程序应该输出: 14 资源约定: 峰值内存消耗(含虚拟机) < 256M CPU消耗 < 2000ms
return res
之前取余数. 最终有3个测试用例过不了, 因为每次递归的结果都有可能超过1000000007, 最后才进行取余在样本量极大的情况下是会出错的.public class T9 { public static int n; public static int m; public static int k; public static int[][][][] dp = new int[50][50][15][15];//用于记忆搜索 public static int[][] arr = new int[50][50]; public static void main(String[] args) { //处理输入 Scanner sc = new Scanner(System.in); n = sc.nextInt(); m = sc.nextInt(); k = sc.nextInt(); for(int i = 0; i < n; i++){ for(int j = 0; j < m; j++){ arr[i][j] = sc.nextInt(); } } initDp();//初始化记忆数组,不能用java初始的0值,因为很多格子只有0种可能, 会造成重复搜索. System.out.println(process(arr, 0, 0, -1, 0));//宝藏的最小值为0, 所以初始的max值为-1 } public static int process(int[][] arr, int x, int y, int max, int cur){ if(dp[x][y][max + 1][cur] != -1){//max初始为-1,为防止越界填入max+1 return dp[x][y][max + 1][cur]; } if(x >= n || y >= m || cur > k){ return 0; } int value = arr[x][y]; if(x == n - 1 && y == m - 1){ if(cur == k || (value > max && cur == k - 1)){ return 1; } return 0; } int res = 0; if(value > max){//如果宝藏大于当前手上的最大值, 就可以拿走. res += process(arr, x, y + 1, value, cur + 1);//每次递归完对结果取模, 否则数据量大的时候会出错. res %= 1000000007; res += process(arr, x + 1, y, value, cur + 1); res %= 1000000007; } //不拿走 res += process(arr, x, y + 1, max, cur); res %= 1000000007; res += process(arr, x + 1, y, max, cur); res %= 1000000007; dp[x][y][max + 1][cur] = res; return res; } public static void initDp(){ for(int i = 0; i < 50; i++){ for(int j = 0; j < 50; j++){ for(int k = 0; k < 15; k++){ for(int l = 0; l < 15; l++){ dp[i][j][k][l] = -1; } } } } } }
i*x 行,第 j*y
列的硬币进行翻转。-【数据格式】
【样例输入】 2 3 【样例输出】 1 【数据规模】 对于10%的数据,n、m <= 10^3; 对于20%的数据,n、m <= 10^7; 对于40%的数据,n、m <= 10^15; 对于10%的数据,n、m <= 10^1000(10的1000次方)。 资源约定: 峰值内存消耗(含虚拟机) < 256M CPU消耗 < 2000ms
第i*x 行,第j*y
列的硬币进行翻转. 也就是说现在定位的硬币坐标是x,y, 是x的倍数的行都要翻, 是y的倍数的列也要翻.(x的因子数 * y的因子数)
那么多次x中有多少个平方数
和y中有多少个平方数
.原数位数 / 2 + 1
这么多位.import java.math.BigInteger; import java.util.Arrays; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String n = sc.next(); String m = sc.next(); System.out.println(sqrt(n).multiply(sqrt(m))); } public static BigInteger sqrt(String num){ int numLen = num.length();//要开方的数字位数 int resLen = (numLen & 1) == 0 ? numLen / 2 : numLen / 2 + 1;//开方后数字的位数 char[] arr = new char[resLen];//用于尝试结果的数组 Arrays.fill(arr, '0'); BigInteger target = new BigInteger(num); for(int pos = 0; pos < resLen; pos++){ for(char i = '1'; i <= '9'; i++){ arr[pos] = i; BigInteger pow = new BigInteger(String.valueOf(arr)).pow(2); if(pow.compareTo(target) == 1){ arr[pos] -= 1; break; } } } return new BigInteger(String.valueOf(arr)); } }