本文共 11071 字,大约阅读时间需要 36 分钟。
X老板脾气古怪,他们公司的电话分机号都是3位数,老板规定,所有号码必须是降序排列,且不能有重复的数位。比如:
751,520,321 都满足要求,而,
766,918,201 就不符合要求。现在请你计算一下,按照这样的规定,一共有多少个可用的3位分机号码?
请直接提交该数字,不要填写任何多余的内容。
这道题的解题方法很简单,根据题目的要求,枚举每一个三位数进行检查就可以解决问题
枚举+检查public class question1 { static int ans=0; public static void main(String args[]) { int ans=0; //根据题目要求,三位不重复的数,且依次递减,因为范围很小,我们可以直接枚举在这个区间的每一个数,最小值是210,最大值应该为987 for(int i=210;i<=987;i++) { int num=i; int a,b,c; a=num%10; //第三位数字 b=num/10%10; //第二位数字 c=num/100; //第一位数字 //判断当前分机号的三位数字依次递减且不存在重复数字 if(a
如【图1.png】的五星图案节点填上数字:1~12,除去7和11。
要求每条直线上数字和相等。如图就是恰当的填法。
请你利用计算机搜索所有可能的填法有多少种。
注意:旋转或镜像后相同的算同一种填法。请提交表示方案数目的整数,不要填写任何其它内容。
| |
全排列+检查+回溯
/* 解题思路 这道题可以变成对1,2,3,4,5,6,8,9,10,12几个数字进行全排列 然后检查每种排列是否满足要求,满足要求就将填发增加1 因为旋转或镜像后相同的算作同一种方法,可以每种填发可以经过旋转可以有5种形式,经过镜像之后有5中形式 将最后算的的结果除以10就是最终的答案 */public class question2 { static int count=0; public static void main(String args[]) { int[] a= { 1,2,3,4,5,6,8,9,10,12}; f(a,0,a.length-1); System.out.println("ans="+count/10); //满足条件的全排列的数量除以10,就是本题的结果 } private static void f(int[] a, int start, int end) { if(start==end) { //全排列完成,检查排列的结果,如果满足要求就将解法加一 if(check(a)) count++; } //将当前位后面的每一位都和当前的这一位数字发生交换,完成全排列 for (int i = start; i <= end; i++) { swap(a,i,start); //交换 f(a, start+1, end); swap(a,i,start); //回溯,将这次循环中的交换恢复,保证数组的内容不发生变化 } } //检查排列结果,即对每一条边上的值求和,判断各条边是否相等 private static boolean check(int[] a) { int x=a[1]+a[4]+a[5]+a[6]; int y=a[1]+a[3]+a[7]+a[8]; int z=a[2]+a[4]+a[8]+a[9]; int h=a[0]+a[3]+a[5]+a[9]; int m=a[0]+a[2]+a[6]+a[7]; if(x==y&&x==z&&x==h&&x==m) return true; return false; } //交换数组中的两个指定下标的元素 private static void swap(int[] a, int i, int start) { int b=a[i]; a[i]=a[start]; a[start]=b; }}
标题:显示二叉树排序二叉树的特征是:某个节点的左子树的所有节点值都不大于本节点值。某个节点的右子树的所有节点值都不小于本节点值。为了能形象地观察二叉树的建立过程,小明写了一段程序来显示出二叉树的结构来。class BiTree{ private int v; private BiTree l; private BiTree r; public BiTree(int v){ this.v = v; } public void add(BiTree the){ if(the.v < v){ if(l==null) l = the; else l.add(the); } else{ if(r==null) r = the; else r.add(the); } } public int getHeight(){ int h = 2; int hl = l==null? 0 : l.getHeight(); int hr = r==null? 0 : r.getHeight(); return h + Math.max(hl,hr); } public int getWidth(){ int w = (""+v).length(); if(l!=null) w += l.getWidth(); if(r!=null) w += r.getWidth(); return w; } public void show(){ char[][] buf = new char[getHeight()][getWidth()]; printInBuf(buf, 0, 0); showBuf(buf); } private void showBuf(char[][] x){ for(int i=0; ip2) buf[y+1][p3] = '\\'; if(l!=null) l.printInBuf(buf,x,y+2); if(r!=null) r.printInBuf(buf,p2+sv.length(),y+2); } private int getRootPos(int x){ return l==null? x : x + l.getWidth(); }}public class Main{ public static void main(String[] args) { BiTree tree = new BiTree(500); tree.add(new BiTree(200)); tree.add(new BiTree(509)); tree.add(new BiTree(100)); tree.add(new BiTree(250)); tree.add(new BiTree(507)); tree.add(new BiTree(600)); tree.add(new BiTree(650)); tree.add(new BiTree(450)); tree.add(new BiTree(510)); tree.add(new BiTree(440)); tree.add(new BiTree(220)); tree.show(); }}对于上边的测试数据,应该显示出: | /--------------500---\ | |/--200---\ /--509---\| | | |100 /--250---\ 507 /--600\ | | | | 220 /--450 510 650 | 440(如有对齐问题,请参考【图1.png】)请分析程序逻辑,填写划线部分缺失的代码。注意,只填写缺少的部分,不要填写已有的代码或符号,也不要加任何说明文字。
对于这种代码填空的题目,完全没有必要完全看懂代码,既然只让写一行代码,那就肯定是关键的语句,可以使用Debug的方式来解决这种题目,先把要填写代码的行注释掉,然后运行这段代码,观察实际输出的结果和题目又什么差别,然后再去填写代码,基本上要填写的哪一行里就是在程序中定义过却从未使用的变量,或者是比较关键的变量,掌握这种思路求解这类问题就会很简单。
buf[y+1][i+p2]=sv.toCharArray()[i];
X星的坦克战车很奇怪,它必须交替地穿越正能量辐射区和负能量辐射区才能保持正常运转,否则将报废。
某坦克需要从A区到B区去(A,B区本身是安全区,没有正能量或负能量特征),怎样走才能路径最短?已知的地图是一个方阵,上面用字母标出了A,B区,其它区都标了正号或负号分别表示正负能量辐射区。
例如:A + - + -- + - - +- + + + -+ - + - +B + - + -
坦克车只能水平或垂直方向上移动到相邻的区。
数据格式要求:
输入第一行是一个整数n,表示方阵的大小, 4<=n<100
接下来是n行,每行有n个数据,可能是A,B,+,-中的某一个,中间用空格分开。 A,B都只出现一次。要求输出一个整数,表示坦克从A区到B区的最少移动步数。
如果没有方案,则输出-1例如:
用户输入:5A + - + -- + - - +- + + + -+ - + - +B + - + -
则程序应该输出:
10资源约定:
峰值内存消耗(含虚拟机) < 512M CPU消耗 < 2000ms求解在图中的最短路径问题,用到的算法大多数都是BFS(广度优先搜索),因为是广度优先搜索,所以找到的结果就是最短路径。
明确了要用到的算法,接下来问题就会变得简单很多,无非就是节点能不能走得通的判断 从起始位置进行BFS,搜索四周的几个节点,如果节点在地图范围内且可以行走(可以行走的条件是下一个节点的值和本节点不同,即题目所说的坦克必须交替穿越正能量辐射区和负能量辐射区),则在下一步走到四周的某一个可以走得通的节点,并将路径数目增加1,一直到找到B节点退出BFS,路径距离即为所求。首先定义一个节点的类Node,用来存储每一个可以行走的节点,接着声明一个队列Queue,用来存储可以走的通的节点,不停执行入队和出队操作,直到当前队列为空(走不通)时结束,返回-1,或者走到B节点,返回路径长度。
因为行走过程中可能会重复走过一个节点,为了优化代码,降低时间复杂度,可以设置一个二维的布尔数组,用来标记一个节点是否被走过,若走过则不在对该节点执行入队操作队列,BFS,字符串处理,节点判断,代码优化
import java.util.LinkedList;import java.util.Queue;import java.util.Scanner;public class question4 { //字符数组,用来存储地图 static char[][] array; static int n; public static void main(String args[]) { Scanner in=new Scanner(System.in); //对用户输入进行处理,此处不做解析 n=in.nextInt(); array=new char[n][n]; String s=""; in.nextLine(); for (int i = 0; i < n; i++) { s=in.nextLine().replaceAll(" ", ""); for (int j = 0; j < n; j++) { array[i][j]= s.toCharArray()[j]; } } int x=0,y=0; //查找A节点,即起始位置,从该处开始执行BFS for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if(array[i][j]=='A') { x=i;y=j; } } if(x!=0) break; } //实例化一个节点,从此处开始查找 Node node=new Node(x, y, 'A', 0); System.out.println(f(node)); } private static int f(Node node) { Queueq=new LinkedList (); //声明一个队列,存储当前可以走的通的节点 q.add(node); //起始节点入队 boolean[][] flag=new boolean[n][n]; //标志数组,标记每一个节点是否被走过 int[] x= { 1,0,-1,0}; int[] y= { 0,1,0,-1}; while (!q.isEmpty()) { //如果队列非空 Node now=q.peek(); //取出队头节点 flag[now.x][now.y]=true; //标记该节点已经被访问过了 q.remove(); //移除已经访问过的节点 for(int i=0;i<4;i++) { //遍历当前节点的四周节点 //遍历当前节点的四周的每个节点 //得到当前节点的下一个节点的位置和属性 int next_x=now.x+x[i]; int next_y=now.y+y[i]; if(next_x<0||next_x>=n||next_y<0||next_y>=n) //如果这个节点不在地图范围内,直接退出,寻找下一个相邻节点 continue; char next_value=array[next_x][next_y]; int next_step=now.step+1; if(next_value=='B') //如果这个节点是B,返回路径长度 return next_step; if(now.value!=next_value&&flag[next_x][next_y]==false) //当前节点和下一个节点不同(交替穿越正负能量区),且下一个节点没有没有访问过,将其加入队尾 { Node next=new Node(next_x, next_y, next_value, next_step); q.add(next); } } } //如果走不通,返回-1 return -1; } }//节点类,标记图中的每一个节点class Node{ int x; //节点的x坐标 int y; //节点的y坐标 char value; //节点的值 int step; //到达该节点的最短路径长度 public Node(int x, int y, char value, int step) { super(); this.x = x; this.y = y; this.value = value; this.step = step; }}
某次无聊中, atm 发现了一个很老的程序。这个程序的功能类似于 Excel ,它对一个表格进行操作。
不妨设表格有 n 行,每行有 m 个格子。 每个格子的内容可以是一个正整数,也可以是一个公式。 公式包括三种:标准差即为方差的平方根。
方差就是:每个数据与平均值的差的平方的平均值,用来衡量单个数据离开平均数的程度。公式都不会出现嵌套。
如果这个格子内是一个数,则这个格子的值等于这个数,否则这个格子的值等于格子公式求值结果。
输入这个表格后,程序会输出每个格子的值。atm 觉得这个程序很好玩,他也想实现一下这个程序。
「输入格式」
第一行两个数 n, m 。 接下来 n 行输入一个表格。每行 m 个由空格隔开的字符串,分别表示对应格子的内容。 输入保证不会出现循环依赖的情况,即不会出现两个格子 a 和 b 使得 a 的值依赖 b 的值且 b 的值依赖 a 的值。「输出格式」
输出一个表格,共 n 行,每行 m 个保留两位小数的实数。 数据保证不会有格子的值超过 1e6 。「样例输入」
3 2 1 SUM(2,1:3,1) 2 AVG(1,1:1,2) SUM(1,1:2,1) STD(1,1:2,2)「样例输出」
1.00 5.00 2.00 3.00 3.00 1.48「数据范围」
对于 30% 的数据,满足: n, m <= 5 对于 100% 的数据,满足: n, m <= 50资源约定:
峰值内存消耗(含虚拟机) < 512M CPU消耗 < 2000ms递归求解每一个公式的结果。
声明一个double的二维数组存放格子的数字,声明一个String二维数组存放用书输入每一个格子的内容,声明一个boolean二维数标记每一个格子是公式还是数值。
对于是公式的格子,根据公式类型调用对应的函数求解,因为平均值和方差都需要用到求和公式,所以只需在求和函数sum()里面进行递归操作,详细操作参考程序代码,本题不做详细解释。
本题需要定义5个方法
static void f(int i, int j) //求解一个公式的格子,将结果赋给存放数值的数组,并将格子标记为是一个数字 double sum(int x1,int y1,int x2,int y2) //求解(x1,y1,x2,y2)范围内的和 static double avg(int x1,int y1,int x2,int y2) //求解(x1,y1,x2,y2)范围内的平均数 double std(int x1,int y1,int x2,int y2) //求解(x1,y1,x2,y2)范围内的标准差 boolean check(String s) //检查一个字符串是不是公式,如果是返回true,不是返回false
import java.io.StreamCorruptedException;import java.util.Scanner;import java.util.regex.Matcher;import java.util.regex.Pattern;public class question5 { static int n,m; static String[][] str; static double[][] array; static boolean[][] flag; public static void main(String args[]) { //首先解决输入问题 Scanner in=new Scanner(System.in); n=in.nextInt(); m=in.nextInt(); str=new String[n][m]; array=new double[n][m]; flag=new boolean[n][m]; in.nextLine(); //将剩余的空行读出,开始接收数据 for (int i = 0; i < n; i++) { String[] s=in.nextLine().split(" "); for (int j = 0; j < m; j++) { str[i][j]=s[j]; } } //输入问题已解决,开始进行数据的转换,首先进行初始数据的转换,就是用户刚开始输入的内容 for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if(check(str[i][j])) continue; flag[i][j]=true; array[i][j]=Double.parseDouble(str[i][j]); } } for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if(!flag[i][j]) { //如果当前的这个格子不是数字,进行转换 f(i,j); } } } //数据转换已完成,开始向外输出数据 for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { System.out.printf("%.2f\t",array[i][j]); } System.out.println(); } } private static void f(int i, int j) { double ans=0; String[] value=((String) str[i][j].subSequence(4, str[i][j].length()-1)).split(":"); //将里面的四个值提取出来 int x1=Integer.parseInt(value[0].split(",")[0]); int y1=Integer.parseInt(value[0].split(",")[1]); int x2=Integer.parseInt(value[1].split(",")[0]); int y2=Integer.parseInt(value[1].split(",")[1]); if(((String)str[i][j].subSequence(0, 3)).equals("SUM")) ans=sum(x1,y1,x2,y2); if(((String)str[i][j].subSequence(0, 3)).equals("AVG")) ans=avg(x1,y1,x2,y2); if(((String)str[i][j].subSequence(0, 3)).equals("STD")) ans=std(x1,y1,x2,y2); array[i][j]=ans; flag[i][j]=true; } //这三个函数是三个公式 static double sum(int x1,int y1,int x2,int y2) { double sum=0; for (int i = x1-1; i < x2; i++) { for (int j = y1-1; j < y2; j++) { if(!flag[i][j]) f(i, j); sum+=array[i][j]; } } return sum; } static double avg(int x1,int y1,int x2,int y2) { double sum=0; sum=sum(x1, y1, x2, y2); int count=(x2-x1+1)*(y2-y1+1); sum=sum/count; return sum; } static double std(int x1,int y1,int x2,int y2) { double avg=avg(x1, y1, x2, y2); double sum=0; int count=(x2-x1+1)*(y2-y1+1); for (int i = x1-1; i < x2; i++) { for (int j = y1-1; j < y2; j++) { sum+=Math.pow((array[i][j]-avg), 2); } } sum=sum/count; //方差 sum=Math.sqrt(sum); //标准差 return sum; } //检查一个字符串是不是公式,如果是返回true,不是返回false static boolean check(String s) { char c=s.toCharArray()[0]; if(c>60) return true; else return false; } }/*样例输入3 21 SUM(2,1:3,1)2 AVG(1,1:1,2)SUM(1,1:2,1) STD(1,1:2,2)样例输出1.00 5.002.00 3.003.00 1.48 */
转载地址:http://qwezi.baihongyu.com/