public class One { public static void main(String[] args) { int sum = 0; for(int i = 1; i <= 100; i++){ sum += count(i); } System.out.println(sum); } public static int count(int num){ int sum = 0; for(int i = 1; i <= num; i++){ sum += i; } return sum; } }
答案: 171700
public class Main { public static void main(String[] args) { for(int i = 1; ; i++){ if(process(i) == -1){ continue; }else{ System.out.println(i); return; } } } public static int process(int n){ int sum = 0; for(int i = n;; i++){ sum += i; if(sum == 236){ return n; }else if(sum > 236){ return -1; } } } }
答案: 26
B DEF A + --- + ------- = 10 C GHI
public class Main { public static float[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9}; public static int res = 0; public static void main(String[] args) { process(0); System.out.println(res); } public static void process(int index){ if(index == arr.length){ check(); return; } for(int i = index; i < arr.length; i++){ swap(i, index); process(index + 1); swap(i, index); } } public static void check(){ float jiaShu = arr[0]; float fenZi1 = arr[1]; float fenMu1 = arr[2]; float fenZi2 = arr[3] * 100 + arr[4] * 10 + arr[5]; float fenMu2 = arr[6] * 100 + arr[7] * 10 + arr[8]; if(jiaShu + (fenZi1 / fenMu1) + (fenZi2 / fenMu2) == 10){ res++; } } public static void swap(int i, int j){ float temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } }
答案: 29
该程序的正常输出为: ABC DEF GHI ABC DEG FHI ABC DEH FGI ABC DEI FGH ABC DFG EHI ABC DFH EGI ABC DFI EGH ABC DGH EFI ABC DGI EFH ABC DHI EFG ABC EFG DHI ABC EFH DGI ABC EFI DGH ABC EGH DFI ABC EGI DFH ABC EHI DFG ABC FGH DEI ABC FGI DEH ABC FHI DEG ABC GHI DEF ABD CEF GHI ABD CEG FHI ABD CEH FGI ABD CEI FGH ABD CFG EHI ABD CFH EGI ABD CFI EGH ABD CGH EFI ABD CGI EFH ABD CHI EFG ABD EFG CHI ..... (以下省略,总共560行)。 public class A { public static String remain(int[] a) { String s = ""; for(int i=0; i<a.length; i++){ if(a[i] == 0) s += (char)(i+'A'); } return s; } public static void f(String s, int[] a) { for(int i=0; i<a.length; i++){ if(a[i]==1) continue; a[i] = 1; for(int j=i+1; j<a.length; j++){ if(a[j]==1) continue; a[j]=1; for(int k=j+1; k<a.length; k++){ if(a[k]==1) continue; a[k]=1; System.out.println(__________________________________); //填空位置 a[k]=0; } a[j]=0; } a[i] = 0; } } public static void main(String[] args) { int[] a = new int[9]; a[0] = 1; for(int b=1; b<a.length; b++){ a[b] = 1; for(int c=b+1; c<a.length; c++){ a[c] = 1; String s = "A" + (char)(b+'A') + (char)(c+'A'); f(s,a); a[c] = 0; } a[b] = 0; } } }
答案:
s + " " + (char)(i + 'A') + (char)(j + 'A') + (char)(k + 'A') + " " + remain(a)
DEFFF CEFFF CDFFF CDEFF CCFFF CCEFF CCDFF CCDEF BEFFF BDFFF BDEFF BCFFF BCEFF BCDFF BCDEF .... (以下省略,总共101行) public class A { public static void f(int[] a, int k, int n, String s) { if(k==a.length){ if(n==0) System.out.println(s); return; } String s2 = s; for(int i=0; i<=a[k]; i++){ _____________________________; //填空位置 s2 += (char)(k+'A'); } } public static void main(String[] args) { int[] a = {4,2,2,1,1,3}; f(a,0,5,""); } }
答案:
f(a, k + 1, n - i, s2);
+--+--+--+ | | | | +--+--+--+--+ | | | | | +--+--+--+--+ | | | | +--+--+--+
这道题的递归策略类似八皇后问题, 也就说当来到第一个格子后, 下一个要填的数不是连接着下一个位置的, 也就是说每个位置要填的数字来自于整个样本, 而且要注意回溯, 保证其他递归过程没有出错.
public class Six { public static int[][] dp = new int[5][6]; public static int[] arr = new int[10]; public static int res = 0; public static void main(String[] args) { initDp(); process(1, 2); System.out.println(res); } public static void process(int x, int y){ if(x == 3 && y == 4){ res++; return; } for(int n = 0; n <= 9; n++){ if(arr[n] == 0 && canFill(x, y, n)){ dp[x][y] = n; arr[n] = 1; if(y == 4){ process(x + 1, 1); }else{ process(x, y + 1); } arr[n] = 0; dp[x][y] = -11; } } } public static boolean canFill(int x, int y, int n){ boolean ans = true; for(int i = -1; i <= 1; i++){ for(int j = -1; j <= 1; j++){ if(i == 0 && j == 0) continue; if(Math.abs(dp[x + i][y + j] - n) <= 1){ ans = false; } } } return ans; } public static void initDp(){ for(int i = 0; i < 5; i++){ for(int j = 0; j < 6; j++){ dp[i][j] = -11; } } } }
答案: 1580
首先通过5层for循环枚举选出5数, 难点在于判断这5个数是否是相连的, 可以利用图中标有编号的特性进行判断. 可以直观地看到一个数上面联通的数可-4得到, 下面的数可+4得到, 同理左边是-1, 右边是+1. 但是, 有特殊情况, 比如4+1为5, 理论上4的右边是5, 但是由于换行的原因, 4和5不是联通的. 但是这个方法是好的, 可以通过修改图中的编号继续使用这个方法.
可以把图改成: 1 2 3 4 6 7 8 9 10 11 12 13
public class Seven { public static int res = 0; public static int[] arr = {1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14}; public static int[] p = new int[5]; public static boolean[] visit = new boolean[5]; public static int[] c = {5, -5, 1, -1}; public static void main(String[] args) { for(int a = 0; a < 12; a++){ for(int b = a + 1; b < 12; b++){ for(int c = b + 1; c < 12; c++){ for(int d = c + 1; d < 12; d++){ for(int e = d + 1; e < 12; e++){ p[0] = arr[a]; p[1] = arr[b]; p[2] = arr[c]; p[3] = arr[d]; p[4] = arr[e]; process(0); boolean flag = true; for(int i = 0; i < 5; i++){ if(!visit[i]){ flag = false; } } if(flag){ res++; } cleanVisit(); } } } } } System.out.println(res); } public static void process(int n){ for(int i = 0; i < 4; i++){ int t = p[n] + c[i]; if(t < 1 || t > 14 || t == 5 || t == 10){ continue; } for(int j = 0; j < 5; j++){ if(!visit[j] && p[j] == t){ visit[j] = true; process(j); } } } } public static void cleanVisit(){ for(int i = 0; i < 5; i++){ visit[i] = false; } } }
答案: 116
例如,输入: 5 则程序应该输出: 0 0 1 2 再例如,输入: 12 则程序应该输出: 0 2 2 2 再例如,输入: 773535 则程序应该输出: 1 1 267 838 资源约定: 峰值内存消耗(含虚拟机) < 256M CPU消耗 < 3000ms
这道题是常规的暴力枚举题, 难在如何降低时间复杂度跑过所有的用例, 如果a, b, c, d每个数都穷举以便, 按照最大的输入5000000, 每个数要枚举的次数为10^3级, 一共就是10^12. 太大了, 会超时. 为了能减少次数, 把枚举分成两半, 一半的数据是
a * a + b * b
, 这一半的数据用哈希表存储, 另外一半的数据是c * c + d * d = n - a * a + b * b
. 这样能把枚举的规模缩小一半.
public class Eight { static HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(); public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); for(int c = 0; c * c <= n / 2; c++){ for(int d = c; c * c + d * d <= n; d++){ if(!map.containsKey(c * c + d * d)){ map.put(c * c + d * d, c); } } } for(int a = 0; a * a <= n / 4; a++){ for(int b = a; a * a + b * b <= n; b++){ if(map.containsKey(n - a * a - b * b)){ int c = map.get(n - a * a - b * b); int d = (int) Math.sqrt(n - a * a - b * b - c * c); System.out.println(a + " " + b + " " + c + " " + d); return; } } } }}
例如,输入: 1 2 3 1 2 3 4 5 程序应该输出: + 0 + 0 - 再例如,输入: 1 4 5 10 11 12 13 15 程序应该输出: 0 - 0 + + 再例如,输入: 2 3 5 7 8 9 10 11 程序应该输出: + 0 0 0 0 资源约定: 峰值内存消耗(含虚拟机) < 256M CPU消耗 < 3000ms
public class QuQiuBoYi { public static int[] n = new int[3]; public static int[] m = new int[5]; public static void main(String[] args) { Scanner sc = new Scanner(System.in); for(int i = 0; i < 3; i++){ n[i] = sc.nextInt(); } Arrays.sort(n); for(int i = 0; i < 5; i++){ m[i] = sc.nextInt(); char res = process(m[i], 0, 0);//每输入一局的球数, 就计算一局 System.out.print(res + " "); } } public static char process(int num, int me, int you){ if(num < n[0]){//没球可摸,进行结算 if((me & 1) != 0 && (you & 1) == 0){//我奇数, 对手偶数, 赢 return '+'; }else if((me & 1) == 0 && (you & 1) != 0){//我偶数, 对手奇数, 输 return '-'; }else{ return '0';//平 } } boolean draw = false; for(int i = 0; i < 3; i++){ if(num >= n[i]){ //重点!假设当前这轮是我摸球, 在我摸完球me+n[i]后, 就到对手摸, me和you的位置转换, 设定中间的参数是摸球的一方 char res = process(num - n[i], you, me + n[i]); if(res == '-'){//由于下一轮是对手摸球, 如果他输了 return '+';//我就赢了 }else if(res == '0'){//如果有平局, 要记录下来 draw = true; } } } return draw ? '0' : '-'; } }
public class Nine { public static int[] n = new int[3]; public static int[] m = new int[5]; public static char[][][] cache = new char[1000][2][2]; public static void main(String[] args) { Scanner sc = new Scanner(System.in); for(int i = 0; i < 3; i++){ n[i] = sc.nextInt(); } Arrays.sort(n); for(int i = 0; i < 5; i++){ m[i] = sc.nextInt(); char res = process(m[i], 0, 0); System.out.print(res + " "); } } public static char process(int num, int me, int you){ if(num < n[0]){ if((me & 1) != 0 && (you & 1) == 0){ return '+'; }else if((me & 1) == 0 && (you & 1) != 0){ return '-'; }else{ return '0';//平 } } if(cache[num][me][you] != '\0'){ return cache[num][me][you]; } boolean draw = false; for(int i = 0; i < 3; i++){ if(num >= n[i]){ char res = process(num - n[i], you, ((me + n[i]) & 1) == 0 ? 0 : 1);//只记录奇偶情况 if(res == '-'){ cache[num][me][you] = '+'; return '+'; }else if(res == '0'){ draw = true; } } } if(draw){ cache[num][me][you] = '0'; return '0'; }else{ cache[num][me][you] = '-'; return '-'; } } }
输入格式: 输入第一行包含一个整数n,表示序列的长度。 第二行包含n个正整数,表示输入序列。 输出格式: 输出一行,包含n个数,表示变换后的序列。 例如,输入: 5 1 2 2 1 2 程序应该输出: -1 -2 0 1 1 再例如,输入: 12 1 1 2 3 2 3 1 2 2 2 3 1 程序应该输出: -1 0 -2 -3 1 1 2 2 0 0 2 2 数据规模与约定 对于30%的数据,n<=1000; 对于50%的数据,n<=30000; 对于100%的数据,1 <=n<=100000,1<=ai<=10^9 资源约定: 峰值内存消耗(含虚拟机) < 256M CPU消耗 < 3000ms
按照题目的思路, 使用HashMap记录数的下标, 使用HashSet记录不同种的的数字, 时间复杂度O(N^2), 暴力做法能得30分.
public class Ten { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); long[] arr = new long[n]; for(int i = 0; i < arr.length; i++){ arr[i] = sc.nextInt(); } long[] former = Arrays.copyOf(arr, arr.length); HashMap<Long, Integer> map = new HashMap<Long, Integer>(); for(int i = 0; i < arr.length; i++){ if(!map.containsKey(arr[i])){ map.put(arr[i], i); arr[i] = -arr[i]; }else{ int types = getTypes(map.get(arr[i]), i, former); map.put(arr[i], i); arr[i] = types; } } for(int i = 0; i < arr.length; i++){ System.out.print(arr[i] + " "); } } public static int getTypes(int begin, int last, long[] former){ HashSet<Long> set = new HashSet<Long>(); int index = begin + 1; while(index < last){ set.add(former[index++]); } return set.size(); } }