一、2014年上机真题(专硕)
循环矩阵(第一列和最后一列是相邻的),求该矩阵中最大子矩阵(就是子矩阵中的元素和最大);输入的数据在文件input.txt中读取,输出的结果存入output.txt中;
输入数据的格式如下:(中间只能一个空格,否则就不能存入数组中)
41 1 0 2
5 1 -3 1
2 2 -1 4
-7 -8 0 -5
package kaoyan;
import java.io.*;
public class Practice14 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("input.txt"));
FileOutputStream fos = new FileOutputStream("output.txt",true);
String s;
String[] ss;
int row1,row2,col1,col2; //用来确定矩阵的四个坐标
int max = Integer.MIN_VALUE; //用来存放矩阵中单点的最大值
//读入矩阵的阶数
s = br.readLine();
ss = s.split(" ");
int n = Integer.valueOf(ss[0]);
//创建二位数组,存储读入的矩阵信息,并计算矩阵中单个点的最大值
int[][] rec = new int[n][2*n];
for (int i=0;i<n;++i){
s=br.readLine();
ss = s.split(" ");
for(int j=0;j<n;++j){
rec[i][j] = Integer.valueOf(ss[j]);
rec[i][j+n] = rec[i][j];
if (rec[i][j] > max)
max = rec[i][j];
}
}
int sum;
//计算最大的子矩阵和
for (col1=0;col1<n;++col1){
for (col2=col1+1;col2<col1+n;++col2){
for (row1=0;row1<n;++row1){
for (row2=row1;row2<n;++row2){
sum = getRecVal(rec,row1,row2,col1,col2);
if (sum > max)
max = sum;
}
}
}
}
//将结果输出到output.txt
fos.write(String.valueOf(max).getBytes());
br.close();
fos.close();
}
//通过三个坐标来求子矩阵的值,x为左定点的列,y为右定点的列
public static int getRecVal(int[][] rec,int row1,int row2,int col1,int col2){
int sum = 0;
for (int i=row1;i<=row2;++i){
for (int j=col1;j<=col2;++j){
sum += rec[i][j];
}
}
return sum;
}
}
二、2015年上机真题(专硕)
题目:一个公司下面有N个部门,现在要给每个部门分配任务,分配任务只能按照分配的顺序进行,不能同时分配两个任务,只能一个接一个的分配,但是分配完任务后,该部门可以立刻执行(不间断)。分配一个任务的时间是a,执行的时间是b。你需要做的就是决定分配给每一个部门任务的顺序,使得所有部门完成任务的总时间最短。要求输入由文件输入input.txt 。输出output.txt。
例子
输入 input.txt
3 (代表3个部门)
2 2
3 4
1 5 (第一组数据,前面为分配时间,后面为执行时间)
2 4
4 2
3 3 (第二组数据)
0 (停止标志)
输出 output.txt
Case 1:8
Case 2: 11
package kaoyan;
import java.io.*;
/*3 (代表3个部门)
2 2
3 4
1 5 (第一组数据,前面为分配时间,后面为执行时间)
8*/
public class Practice2015{
private static int n; //n个部门
private static int[][] a; //存储任务的分配时间和执行时间
private static int min = Integer.MAX_VALUE; //存储所有任务分配并执行完的最小时间和
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new FileReader("input.txt"));
FileOutputStream fos = new FileOutputStream("output.txt");
n = Integer.valueOf(br.readLine());
a = new int[n+1][2];
for (int i=1;i<=n;++i){
String[] strs = br.readLine().split(" ");
a[i][0] = Integer.valueOf(strs[0]);
a[i][1] = Integer.valueOf(strs[1]);
}
distribut(a,n+1,0);
fos.write(String.valueOf(min).getBytes());
br.close();
fos.close();
}
/**
* @param arr 数据
* @param count 数据条数
* @param sum 当前方法已经用掉的时间
* 先计算为两个部门分配并任务所需的必要时间和执行时间,将结果存入b中,继续计算剩下的count-1个部门
*/
public static void distribut(int[][] arr,int count,int sum){
if (count == 1){
min = Math.min(sum + arr[0][1],min);
return;
}
int[][] b = new int[count][2];
for (int i=1;i<count;++i){
//把没计算的放到b中
int m = 1;
//存储促参与计算的count-2的数据
for (int k=1;k<count;++k){
if (k != i){
b[m][0] = arr[k][0];
b[m++][1] = arr[k][1];
}
}
//计算必须时间和执行时间
int temp = sum;
int excuteTime = arr[0][1];
temp += arr[0][0];
if (arr[0][1] > arr[i][0]){
temp += arr[i][0];
excuteTime = arr[0][1] -arr[i][0];
if (excuteTime < arr[i][1])
excuteTime = arr[i][1];
}else if (arr[0][1] == arr[i][0]){
temp += arr[i][0];
excuteTime = arr[i][1];
}else{
temp += arr[i][0];
excuteTime = arr[i][1];
}
//将执行时间存入b中,已用掉的时间放在temp中
b[0][0] = 0;
b[0][1] = excuteTime;
distribut(b,m,temp);
}
}
}
三、2017年上机真题(专硕)
小明玩一个游戏,小明手上有一张牌,桌子上有六张牌,游戏规则是,求用最多的桌上卡牌与小明手中的卡牌进行加减乘除四则运算最后使
果达到13.如小明卡牌是5,桌上卡牌是1 3 9 4 2 2,此题答案即5-1.0-3.0*9.0-2.0+4.0+2.0
即最多可容纳6张牌(此题不考乘除优先级,先到优先,桌上卡牌可重)。
从input.txt中读入数据 | 往output.txt中写入数据 |
5 1 3 9 4 2 2 | 6 |
package kaoyan;
import java.io.*;
public class Practice2017{
private static double[] a; //卡牌
private static int length; //已求得的最长表达式的长度
private static String[] expression; //存储最长的运算的表达式
public static void main(String[] args) throws IOException{
a = new double[]{5,1,3,9,4,2,2}; //这里我直接输入的数据,没用文件读写
expression = new String[13];
expression[0] = "5";
count13(a,7,new String[15],0);
//如果表达式长度为0,则表示不能组成值为13的表达式,返回false,否则输出表达式
if(length != 0){
for (int i=0;i<=length;++i)
System.out.print(expression[i]);
}else
System.out.println(false);
}
//判断n是否为0
public static boolean isZero(double n){
return Math.abs(n) <= 0.00001;
}
//计算值为13的表达式,n为arr的长度,len为exp的长度
public static void count13(double arr[],int n,String[] exp,int len){
if (isZero(arr[0]-13)){
//多个值为13的表达式,选最长的
if (len > length){
length = len;
for (int i=1;i<=len;++i)
expression[i] = exp[i-1];
}
return;
}else if (n == 1) //不能找到值为13的表达式
return;
double[] b = new double[13];
for (int i=1;i<n;++i){
//把剩下的没计算的数放到b中
int m = 1;
for (int k=1;k<n;++k){
if (k != i)
b[m++] = arr[k];
}
int tempLen = len;
b[0] = arr[0] - arr[i];
exp[tempLen++] = "-";
exp[tempLen++] = String.valueOf(arr[i]);
count13(b,m,exp,tempLen);
tempLen = len;
b[0] = arr[0] + arr[i];
exp[tempLen++] = "+";
exp[tempLen++] = String.valueOf(arr[i]);
count13(b,m,exp,tempLen);
tempLen = len;
b[0] = arr[0] * arr[i];
exp[tempLen++] = "*";
exp[tempLen++] = String.valueOf(arr[i]);
count13(b,m,exp,tempLen);
if (!isZero(arr[i])){
tempLen = len;
b[0] = arr[0] / arr[i];
exp[tempLen++] = "/";
exp[tempLen++] = String.valueOf(arr[i]);
count13(b,m,exp,tempLen);
}
}
}
}