问题描述
请实现一个铁路购票系统的简单座位分配算法,来处理一节车厢的座位分配。
假设一节车厢有20排、每一排5个座位。为方便起见,我们用1到100来给所有的座位编号,第一排是1到5号,第二排是6到10号,依次类推,第20排是96到100号。
购票时,一个人可能购一张或多张票,最多不超过5张。如果这几张票可以安排在同一排编号相邻的座位,则应该安排在编号最小的相邻座位。否则应该安排在编号最小的几个空座位中(不考虑是否相邻)。
假设初始时车票全部未被购买,现在给了一些购票指令,请你处理这些指令。
输入格式
输入的第一行包含一个整数n,表示购票指令的数量。
第二行包含n个整数,每个整数p在1到5之间,表示要购入的票数,相邻的两个数之间使用一个空格分隔。
输出格式
输出n行,每行对应一条指令的处理结果。
对于购票指令p,输出p张车票的编号,按从小到大排序。
样例输入
4
2 5 4 2
样例输出
1 2
6 7 8 9 10
11 12 13 14
3 4
package test;
import java.util.*;
public class Main {
public static void main(String[] args) {
/*
输入的第一行包含一个整数n,表示购票指令的数量。
第二行包含n个整数,每个整数p在1到5之间,表示要购入的票数,相邻的两个数之间使用一个空格分隔。
输出格式
输出n行,每行对应一条指令的处理结果。
对于购票指令p,输出p张车票的编号,按从小到大排序。
*/
Scanner in=new Scanner(System.in);
int n;
n=in.nextInt();
int []buyTickets=new int[n];
for(int i=0;i<n;i++){
buyTickets[i]=in.nextInt();
}
int [][]seats=new int[20][5]; //num=5*i+j+1,0表示未购买,1表示购买了;
for(int i=0;i<n;i++){
int num=buyTickets[i];
int []flag=findContinueSeats(seats,num);
if(flag[0]==-1){ //表示没有连续的空座位
for(int p=0;p<20&&num>0;p++){
for(int q=0;q<5&&num>0;q++){
if(seats[p][q]==0){
seats[p][q]=1;
num--;
System.out.print(p*5+q+1+" ");
}
}
}
}
else{ //有连续的空座位,且flag[0]表示那一行,flag[1]表示那一行连续空闲位置开始的位置。
int row=flag[0];
int col=flag[1];
while(num>0){
System.out.print(row*5+col+1+" ");
seats[row][col++]=1;
num--;
}
}
System.out.println();
}
}
public static int[] findContinueSeats(int[][]seats,int num){
int[] record=new int[2];
record[0]=record[1]=-1;
place:
for(int i=0;i<20;i++){ //一行一行找
int continueEmptySeats=0;
int j;
for(j=0;j<5;j++){
if(seats[i][j]==0){
continueEmptySeats++;
}
else{
if(continueEmptySeats>=num){
record[0]=i;
record[1]=j-continueEmptySeats;
break place;
}
else{
continueEmptySeats=0;
}
}
}
if(continueEmptySeats>=num){
record[0]=i;
record[1]=j-continueEmptySeats;
break;
}
}
return record;
}
}
数字排序
问题描述
给定n个整数,请统计出每个整数出现的次数,按出现次数从多到少的顺序输出。
输入格式
输入的第一行包含一个整数n,表示给定数字的个数。
第二行包含n个整数,相邻的整数之间用一个空格分隔,表示所给定的整数。
输出格式
输出多行,每行包含两个整数,分别表示一个给定的整数和它出现的次数。按出现次数递减的顺序输出。如果两个整数出现的次数一样多,则先输出值较小的,然后输出值较大的。
样例输入
12
5 2 3 3 1 3 4 2 5 2 3 5
样例输出
3 4
2 3
5 3
1 1
4 1
这一题其实并不难,但是坑就坑在了数组边界值的问题上,还有就是最近在看Map啥的就想用,但是发现这个题目数据其实不大,最大就1000,所以直接用数组更简单方便,最重要的就是他数的value值最大也就1000。复习用java写这个代码的时候改了很多次,一直都是70分,后来发现,我传给冒泡排序的n值不是数组的长度,数组的长度是n+1,n表示数组可到达的最大的index位置,所以导致自己测试的时候的数据都能过,但是却没法得满分,要反思!!!
package test;
import java.util.*;
public class Main {
public static void main(String[] args) {
/*
输入的第一行包含一个整数n,表示给定数字的个数。
第二行包含n个整数,相邻的整数之间用一个空格分隔,表示所给定的整数。
输出多行,每行包含两个整数,分别表示一个给定的整数和它出现的次数。按出现次数递减的顺序输出。
如果两个整数出现的次数一样多,则先输出值较小的,然后输出值较大的。
*/
Scanner in=new Scanner(System.in);
int n;
n=in.nextInt();
int [][]record=new int[1001][2];
int num;
int max=-1;
for(int i=0;i<n;i++){
num=in.nextInt();
record[num][0]=num; //第一位存放数,初始时跟下标相同
record[num][1]++; //第二位存放出现的次数
if(num>max)
max=num;
}
bubbleSort(record,max); //从大到小
for(int i=0;i<=max;i++) {
//System.out.println(record[i][0] + " " + record[i][1]);
if (record[i][1] != 0) {
System.out.println(record[i][0] + " " + record[i][1]);
}
}
}
public static void bubbleSort(int[][]record,int n){ //按降序排序
int[]temp=new int[2];
boolean flag;
for(int i=1;i<n;i++){
flag=false;
for(int j=0;j<n-i+1;j++){
if(record[j][1]<record[j+1][1]){
temp=record[j];
record[j]=record[j+1];
record[j+1]=temp;
flag=true;
}
}
if(flag==false){
break;
}
}
}
}
3. 二十四点
这一题真的是,其实就是数据结构里利用栈进行算数表达式运算,弄两个栈,OP栈和Num就行了,但是真的要注意,看清题目,题目说的乘号是小写的x,我就给写成X的了,看瞎了都找不出50分的原因。。。还是要仔细啊
package test;
import java.util.Scanner;
import java.util.Stack;
public class Main {
private static int [][]operaComp=new int[][]{{1,1,0,0},{1,1,0,0},{1,1,1,1},{1,1,1,1}};
private final static String Y="Yes";
private final static String N="No";
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int n=in.nextInt(); //n个解
String []input=new String[n];
for(int i=0;i<n;i++){
input[i]=in.next();
}
for(int i=0;i<n;i++){
int sum=dealString(input[i]);
if(sum==24)
System.out.println(Y);
else
System.out.println(N);
}
}
public static int operaLocation(char op){
if(op=='+')
return 0;
else if(op=='-')
return 1;
else if(op=='x')
return 2;
else
return 3; //除法操作
}
public static int calStack(char op,int ch2,int ch1){
int result=0;
if(op=='+'){
result=ch1+ch2;
}
else if(op=='-'){
result=ch1-ch2;
}
else if(op=='x'){
result=ch1*ch2;
}
else if(op=='/'){
result=ch1/ch2;
}
return result;
}
public static int dealString(String s){ //用栈!!!
int result=0;
Stack<Integer> stackNum=new Stack<>();
Stack<String> stackOperator=new Stack<>();
for(int i=0;i<s.length();i++){
if(i%2==0){ //是数字
stackNum.push(new Integer((int)(s.charAt(i)-'0')));
//System.out.println((int)(s.charAt(i)-'0')+" 进入stackNum栈");
}
else{
char op2=s.charAt(i);
while(!stackOperator.empty()){
char op1=stackOperator.pop().charAt(0);
int op1i=operaLocation(op1);
int op2i=operaLocation(op2);
int r=operaComp[op1i][op2i];
if(r==1){ //栈内运算;
int x,y;
x=stackNum.pop().intValue();
y=stackNum.pop().intValue();
int calResult=calStack(op1,x,y);
//System.out.println(x+"、"+y+"出stackNum栈,"+op1+"出stackOperator栈," +"运算结果:"+calResult+" 进stackNum栈");
stackNum.push(calResult);
}
else{ //push进去
stackOperator.push(new String(String.valueOf(op1)));
stackOperator.push(new String(String.valueOf(op2)));
//System.out.println(op2+" 进入stackOperator栈");
break;
}
}
if(stackOperator.empty()){
stackOperator.push(new String(String.valueOf(op2)));
//System.out.println(op2+" 进入stackOperator栈");
}
}
}
while(!stackOperator.empty()){
char op=stackOperator.pop().charAt(0);
int ch2,ch1;
ch1=stackNum.pop().intValue();
ch2=stackNum.pop().intValue();
int calResult=calStack(op,ch1,ch2);
stackNum.push(calResult);
}
return stackNum.pop().intValue();
}
}