解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论
题目1、煤球数量煤球数目
有一堆煤球,堆成三角棱锥形。具体:
第一层放1个,
第二层3个(排列成三角形),
第三层6个(排列成三角形),
第四层10个(排列成三角形),
…
如果一共有100层,共有多少个煤球?
请填表示煤球总数目的数字。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
结果:171700
- public class Main {
-
- public static void main(String[] args) {
- long sum = 0;
- long a = 0;
- for(long i = 1;i <= 100;i++) {
- a += i;
- sum += a;
- }
- System.out.println(sum);
- }
- }
题目2、生日蜡烛
生日蜡烛
某君从某年开始每年都举办一次生日party,并且每次都要吹熄与年龄相同根数的蜡烛。
现在算起来,他一共吹熄了236根蜡烛。
请问,他从多少岁开始过生日party的?
请填写他开始过生日party的年龄数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
结果:26
- public class Main {
-
- public static void main(String[] args) {
- for(int i = 1;i <= 100;i++) {
- int sum = i;
- for(int j = i + 1;j <= 100;j++) {
- sum += j;
- if(sum == 236)
- System.out.println("i = "+i+", j = "+j);
- if(sum > 236)
- break;
- }
- }
- }
- }
题目3、凑算式
凑算式
B DEF
A + — + ------- = 10
C GHI
(如果显示有问题,可以参见【图1.jpg】)
这个算式中AI代表19的数字,不同的字母代表不同的数字。
比如:
6+8/3+952/714 就是一种解法,
5+3/1+972/486 是另一种解法。
这个算式一共有多少种解法?
注意:你提交应该是个整数,不要填写任何多余的内容或说明性文字。
(碰到除法问题,要特别注意,如题目未事先声明进行整除,均首先消除分母,进行乘法运算,这样可以消除浮点数误差)
结果:29
- public class Main {
- public static int count = 0;
-
- public void swap(int[] A, int a, int b) {
- int temp = A[a];
- A[a] = A[b];
- A[b] = temp;
- }
-
- public void dfs(int[] A, int step) {
- if(step == A.length) {
- if(check(A))
- count++;
- return;
- } else {
- for(int i = step;i < A.length;i++) {
- swap(A, i, step);
- dfs(A, step + 1);
- swap(A, i, step);
- }
- }
- return;
- }
-
- public boolean check(int[] A) {
- int a1 = A[0] * A[2] * (A[6]*100 + A[7]*10 + A[8]);
- int a2 = A[1] * (A[6]*100 + A[7]*10 + A[8]);
- int a3 = (A[3]*100 + A[4]*10 + A[5]) * A[2];
- if(a1 + a2 + a3 == 10 * A[2] * (A[6]*100 + A[7]*10 + A[8]))
- return true;
- return false;
- }
-
- public static void main(String[] args) {
- Main test = new Main();
- int[] A = {1,2,3,4,5,6,7,8,9};
- test.dfs(A, 0);
- System.out.println(count);
- }
- }
题目4、分小组
- 分小组
-
- 9名运动员参加比赛,需要分3组进行预赛。
- 有哪些分组的方案呢?
-
- 我们标记运动员为 A,B,C,... I
- 下面的程序列出了所有的分组方法。
-
- 该程序的正常输出为:
- 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)
题目5、抽签
- 抽签
-
- X星球要派出一个5人组成的观察团前往W星。
- 其中:
- A国最多可以派出4人。
- B国最多可以派出2人。
- C国最多可以派出2人。
- ....
-
- 那么最终派往W星的观察团会有多少种国别的不同组合呢?
-
- 下面的程序解决了这个问题。
- 数组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)
题目6、方格填数
- 题目描述
- 如下的10个格子
- +--+--+--+
- | | | |
- +--+--+--+--+
- | | | | |
- +--+--+--+--+
- | | | |
- +--+--+--+
-
- (如果显示有问题,也可以参看【图1.jpg】)
-
- 填入0~9的数字。要求:连续的两个数字不能相邻。
- (左右、上下、对角都算相邻)
-
- 一共有多少种可能的填数方案?
-
- 请填写表示方案数目的整数。
- 注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
-
结果:1580
- public class Main {
- public static int count = 0;
-
- public void swap(int[] A, int a, int b) {
- int temp = A[a];
- A[a] = A[b];
- A[b] = temp;
- }
-
- public void dfs(int[] A, int step) {
- if(step == A.length) {
- if(check(A))
- count++;
- return;
- } else {
- for(int i = step;i < A.length;i++) {
- swap(A, i, step);
- dfs(A, step + 1);
- swap(A, i, step);
- }
- }
- return;
- }
-
- public boolean check(int[] A) {
- if(Math.abs(A[0]-A[3]) != 1 && Math.abs(A[0]-A[1]) != 1 && Math.abs(A[0]-A[4]) != 1 && Math.abs(A[0]-A[5]) != 1) {
- if(Math.abs(A[1]-A[4]) != 1 && Math.abs(A[1]-A[5]) != 1 && Math.abs(A[1]-A[2]) != 1 && Math.abs(A[1]-A[6]) != 1) {
- if(Math.abs(A[2]-A[5]) != 1 && Math.abs(A[2]-A[6]) != 1) {
- if(Math.abs(A[3]-A[4]) != 1 && Math.abs(A[3]-A[7]) != 1 && Math.abs(A[3]-A[8]) != 1) {
- if(Math.abs(A[4]-A[5]) != 1 && Math.abs(A[4]-A[7]) != 1 && Math.abs(A[4]-A[8]) != 1 && Math.abs(A[4]-A[9]) != 1) {
- if(Math.abs(A[5]-A[8]) != 1 && Math.abs(A[5]-A[9]) != 1 && Math.abs(A[5]-A[6]) != 1) {
- if(Math.abs(A[6]-A[9]) != 1 && Math.abs(A[7]-A[8]) != 1) {
- if(Math.abs(A[8]-A[9]) != 1)
- return true;
- }
- }
- }
- }
- }
- }
- }
- return false;
- }
-
- public static void main(String[] args) {
- Main test = new Main();
- int[] A = {0,1,2,3,4,5,6,7,8,9};
- test.dfs(A, 0);
- System.out.println(count);
- }
- }
题目7、剪邮票
题目描述
如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
结果:116
- import java.util.ArrayList;
-
- public class Main {
- public ArrayList<Integer> list = new ArrayList<Integer>();
- public static int[] A = {1,2,3,4,5,6,7,8,9,10,11,12};
- public static boolean[] visited = new boolean[5];
- public static long count = 0;
-
- public void dfs(int step) {
- while(step < A.length) {
- list.add(A[step]);
- if(list.size() == 5) {
- if(check()) {
- System.out.println(list);
- count++;
- }
-
- }
- step++;
- dfs(step);
- list.remove(list.size() - 1);
- }
- }
-
- public boolean check() {
- for(int i = 0;i < 5;i++)
- visited[i] = false;
- int start = list.get(0);
- dfsPath(start, 0);
- for(int i = 0;i < 5;i++) {
- if(visited[i] == false)
- return false;
- }
- return true;
- }
-
- public void dfsPath(int a, int i) {
- visited[i] = true;
- int start1 = a + 1;
- int start2 = a - 1;
- int start3 = a + 4;
- int start4 = a - 4;
- int r = (a - 1) / 4;
- if(list.contains(start1) && (start1 - 1) / 4 == r && !visited[list.indexOf(start1)])
- dfsPath(start1, list.indexOf(start1));
- if(list.contains(start2) && (start2 - 1) / 4 == r && !visited[list.indexOf(start2)])
- dfsPath(start2, list.indexOf(start2));
- if(list.contains(start3) && !visited[list.indexOf(start3)])
- dfsPath(start3, list.indexOf(start3));
- if(list.contains(start4) && !visited[list.indexOf(start4)])
- dfsPath(start4, list.indexOf(start4));
- }
-
- public static void main(String[] args) {
- Main test = new Main();
- test.dfs(0);
- System.out.println(count);
- }
- }
题目8、四平方和
四平方和
四平方和定理,又称为拉格朗日定理:
每个正整数都可以表示为至多4个正整数的平方和。
如果把0包括进去,就正好可以表示为4个数的平方和。
比如:
5 = 0^2 + 0^2 + 1^2 + 2^2
7 = 1^2 + 1^2 + 1^2 + 2^2
(^符号表示乘方的意思)
对于一个给定的正整数,可能存在多种平方和的表示法。
要求你对4个数排序:
0 <= a <= b <= c <= d
并对所有的可能表示法按 a,b,c,d 为联合主键升序排列,最后输出第一个表示法
程序输入为一个正整数N (N<5000000)
要求输出4个非负整数,按从小到大排序,中间用空格分开
例如,输入:
5
则程序应该输出:
0 0 1 2
再例如,输入:
12
则程序应该输出:
0 2 2 2
再例如,输入:
773535
则程序应该输出:
1 1 267 838
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 3000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
- import java.util.Scanner;
-
- public class Main {
-
- public static void main(String[] args) {
- Scanner in = new Scanner(System.in);
- int N = in.nextInt();
- int len = (int) Math.sqrt(N);
- for(int a = 0;a <= len;a++) {
- for(int b = a;b <= len;b++) {
- for(int c = b;c <= len;c++) {
- for(int d = c;d <= len;d++) {
- int temp = a*a + b*b + c*c + d*d;
- if(temp == N) {
- System.out.println(a+" "+b+" "+c+" "+d);
- return;
- }
- }
- }
- }
- }
- }
-
- }
题目9、取球博弈
- 取球博弈
-
- 两个人玩取球的游戏。
- 一共有N个球,每人轮流取球,每次可取集合{n1,n2,n3}中的任何一个数目。
- 如果无法继续取球,则游戏结束。
- 此时,持有奇数个球的一方获胜。
- 如果两人都是奇数,则为平局。
-
- 假设双方都采用最聪明的取法,
- 第一个取球的人一定能赢吗?
- 试编程解决这个问题。
-
- 输入格式:
- 第一行3个正整数n1 n2 n3,空格分开,表示每次可取的数目 (0<n1,n2,n3<100)
- 第二行5个正整数x1 x2 ... x5,空格分开,表示5局的初始球数(0<xi<1000)
-
- 输出格式:
- 一行5个字符,空格分开。分别表示每局先取球的人能否获胜。
- 能获胜则输出+,
- 次之,如有办法逼平对手,输出0,
- 无论如何都会输,则输出-
-
- 例如,输入:
- 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
-
-
- 请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
-
- 所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
- 注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
- 注意:主类的名字必须是:Main,否则按无效代码处理。
-
-
- 本题是拈游戏的一个拓展,考查减治法和动态规划法思想的运用,下面代码,对于题中所给三组数据均可以通过,但是对于平局(均为奇数或均为偶数)细节处理问题上有待证明,感觉自己处理的不够严谨。下面代码仅供参考哦~
- import java.util.Scanner;
-
- public class Main {
- public static int[] value = new int[1000];
- public static int[] getN = new int[3];
- public static int[] init = new int[5];
- public static char[] result = {'-','0','0','+'};
-
- public static void main(String[] args) {
- Scanner in = new Scanner(System.in);
- for(int i = 0;i < 3;i++)
- getN[i] = in.nextInt();
- for(int i = 0;i < 5;i++)
- init[i] = in.nextInt();
- int minN = Math.min(getN[0], Math.min(getN[1], getN[2]));
- if(minN % 2 == 1) //此处关于平局,两者是均为奇数,还是均为偶数问题,这里处理原因,是我自己猜想
- value[0] = 1; //代表平局,两者默认均为奇数个
- else
- value[0] = 2; //代表平局,两者默认均为偶数个
- for(int i = 1;i < minN;i++)
- value[i] = 2; //0代表负,1和2代表平局,3代表胜
- for(int i = minN;i < 1000;i++) {
- int temp = 0; //初始化,当前i个球,先取者必输
-
- for(int j = 0;j < 3;j++) {
- if(i - getN[j] < 0)
- continue;
- if(i - getN[j] == 0 && getN[j] % 2 == 1)
- temp = 3;
- if(value[i - getN[j]] == 0) { //表示i - getN[j]个球先取时,必输
- if(getN[j] % 2 == 0)
- temp = 3;
- //此时最终结果为两人取的球均为偶数个,但是若temp取三个数中另外一个数时
- //,是必赢结果,则舍弃这个平局结果
- else
- temp = 2 > temp ? 2 : temp;
- }
- if(value[i - getN[j]] == 1) { //表示i - getN[j]个球先取时,两人取球均为奇数个
- if(getN[j] % 2 == 0)
- temp = 1 > temp ? 1 : temp; //此处做比较同上
- }
- if(value[i - getN[j]] == 2) {//表示i - getN[j]个球先取时,两人取球均为偶数个
- if(getN[j] % 2 == 1)
- temp = 3; //此种情况出现,必赢,不必做比较判断
- else
- temp = 2 > temp ? 2 : temp; //此处比较同上,排除必输情况
- }
- if(value[i - getN[j]] == 3) {//表示i - getN[j]个球先取时,必赢
- if(getN[j] % 2 == 1)
- temp = 1 > temp ? 1 : temp;
- }
- }
-
- value[i] = temp; //当前i个球,先取者最终输赢结果
- }
- //打印题意最终结果
- for(int i = 0;i < 5;i++)
- System.out.print(result[value[init[i]]]+" ");
- }
- }
题目10、压缩变换
压缩变换
小明最近在研究压缩算法。
他知道,压缩的时候如果能够使得数值很小,就能通过熵编码得到较高的压缩比。
然而,要使数值很小是一个挑战。
最近,小明需要压缩一些正整数的序列,这些序列的特点是,后面出现的数字很大可能是刚出现过不久的数字。对于这种特殊的序列,小明准备对序列做一个变换来减小数字的值。
变换的过程如下:
从左到右枚举序列,每枚举到一个数字,如果这个数字没有出现过,刚将数字变换成它的相反数,如果数字出现过,则看它在原序列中最后的一次出现后面(且在当前数前面)出现了几种数字,用这个种类数替换原来的数字。
比如,序列(a1, a2, a3, a4, a5)=(1, 2, 2, 1, 2)在变换过程为:
a1: 1未出现过,所以a1变为-1;
a2: 2未出现过,所以a2变为-2;
a3: 2出现过,最后一次为原序列的a2,在a2后、a3前有0种数字,所以a3变为0;
a4: 1出现过,最后一次为原序列的a1,在a1后、a4前有1种数字,所以a4变为1;
a5: 2出现过,最后一次为原序列的a3,在a3后、a5前有1种数字,所以a5变为1。
现在,给出原序列,请问,按这种变换规则变换后的序列是什么。
输入格式:
输入第一行包含一个整数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
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.Scanner;
-
- public class Main {
- public static int[] arrayN;
-
- public int getValue(int[] tempN, int position) {
- if(position == 0)
- return -1;
- int i = position - 1;
- for(;i >= 0;i--) {
- if(tempN[i] == tempN[position])
- break;
- if(i == 0)
- i--;
- }
- if(i < 0)
- return -1;
- ArrayList<Integer> list = new ArrayList<Integer>();
- i = i + 1;
- for(;i < position;i++)
- list.add(tempN[i]);
- if(list.size() == 0)
- return 0;
- Collections.sort(list);
- int count = 1;
- for(int j = 1;j < list.size();j++) {
- if(list.get(j) != list.get(j - 1))
- count++;
- }
- return count;
- }
-
- public void getResult() {
- int len = arrayN.length;
- int[] tempN = new int[len];
- for(int i = 0;i < len;i++)
- tempN[i] = arrayN[i];
- for(int i = 0;i < len;i++) {
- int value = getValue(tempN, i);
- if(value == -1)
- arrayN[i] = (-1) * arrayN[i];
- else
- arrayN[i] = value;
- }
- //打印最终结果
- for(int i = 0;i < len;i++)
- System.out.print(arrayN[i]+" ");
- }
-
-
- public static void main(String[] args) {
- Main test = new Main();
- Scanner in = new Scanner(System.in);
- int n = in.nextInt();
- arrayN = new int[n];
- for(int i = 0;i < n;i++)
- arrayN[i] = in.nextInt();
- test.getResult();
- }
-
- }