CSP 火车购票--java100分 数字排序--java100分

问题描述
  请实现一个铁路购票系统的简单座位分配算法,来处理一节车厢的座位分配。
  假设一节车厢有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();
    }
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值