蓝桥杯 算法提高 判断名次

博客围绕蓝桥杯算法提高题“判断名次”展开。已知A~E五人比赛,第1、3、5名说假话,给出五人所说的名次判断。解题思路是生成所有排序可能,依据每人话语判断排序是否符合条件,还给出了输入输出格式及样例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

判断名次

问题描述

某场比赛过后,你想要知道A~E五个人的排名是什么,于是要求他们每个人说了一句话。(经典的开头……-_-!)得了第1名的人23,说了假话;得了第5名的人不好意思,也说了假话;为了使求解问题简单,第3名同样说了假话。(奇数名次说假话)

输入格式

共5行,各行依次表示A ~ E说的话。每行包含一个形如“A>=3”的名次判断,即一个大写字母+关系运算符+一个数字,不包含空格。大写字母A ~ E,关系运算<、<=、=、>=、>、!=,数字1~5。注意:等于是“=”不是“==”!

输出格式

可能有多解,请按照字典序输出排名序列,每个解一行。最后一行输出解的数量

样例输入

A=2
D=5
E>3
A>2
B!=1

样例输出

ACDEB
AECBD
BADCE
BCADE
BDACE
CEADB
CEBDA
7

解题思路

题中确定为五个人的名词排序,可以先生成所有的排序可能,再根据相应位置上的每个人说的话来判断此排序是否符合条件。

程序实现

import java.util.ArrayList;
import java.util.Scanner;

public class LogicalProblem {
    //定义五个人,方便递归输出所有排序可能
    public static char[] charAr={'A','B','C','D','E'};
    //储存符合条件的排序
    public static ArrayList<ArrayList<Character>> list=new ArrayList<>();
    //五个人说的五句话
    public static String[] JudgeAr=new String[5];

    public static void main(String[] args){
        Scanner in=new Scanner(System.in);
        for(int i=0;i<5;i++){
            String line=in.nextLine();
            JudgeAr[i]=line;
        }
        list.add(new ArrayList<>());
        boolean[] Mark=new boolean[5];
        //找出所有的排序方式并储存在list中
        StringGeneration(Mark,0);
        //递归后最后一条为空,需要删除
        list.remove(list.size()-1);
        //输出结果
        for(ArrayList<Character> li:list){
            for(Character ch:li){
                System.out.print(ch);
            }
            System.out.println();
        }
        System.out.print(list.size());

    }

    /**
     * 递归生成所有排序可能,并将符合条件的可能保存到{@param list}中
     * @param Mark 标记那些人已经处于排序队列中
     * @param length 当前排序队列中的人数
     */
    public static void StringGeneration(boolean[] Mark,int length){
        if(length==5){
            //判断当前排序队列是否符合要求,符合要求的保存在list中!!
            if(Judge(list.get(list.size()-1))){
                ArrayList<Character> newlist=(ArrayList<Character>)(list.get(list.size()-1).clone());
                list.add(newlist);
            }
            return;
        }
        for(int i=0;i<5;i++){
            if(!Mark[i]){
                list.get(list.size()-1).add(charAr[i]);
                Mark[i]=true;
                StringGeneration(Mark,length+1);
                list.get(list.size()-1).remove(length);
                Mark[i]=false;
            }
        }
        return;
    }

    /**
     * 判断当前名次排序是否符合条件
     * @param charList 当前名次排序
     * @return 符合 return true; 不符合 return false
     */
    public static boolean Judge(ArrayList<Character> charList){
        int[] charLoca=new int[5];
        for(int i=0;i<5;i++){
            int Loca=charList.get(i)-'A';
            charLoca[Loca]=i;
        }
        for(int i=0;i<5;i++){
            int Loca=charList.get(i)-'A';
            ArrayList<Integer> Evaluation=getLoca(JudgeAr[Loca]);
            int OLoca=JudgeAr[Loca].charAt(0)-'A';
            //排第1,3,5位的人说假话,2,4位的人说真话
            if(i%2==0){
                if(Evaluation.contains(charLoca[OLoca]))
                    return false;
            }else{
                if(!Evaluation.contains(charLoca[OLoca]))
                    return false;
            }
        }
        return true;
    }

    /**
     * 当这句话为真时,话中的对象可能的名次:优化方法:程序运行开始就可以将五句话对应状态状态全部保存,避免重复运算
     * @param string 当前这个人说的话
     * @return 可能的名次
     */
    public static ArrayList<Integer> getLoca(String string){
        char[] charAr=string.toCharArray();
        ArrayList<Integer> result=new ArrayList<>();
        if(charAr.length==4){
            int value=charAr[3]-'1';
            if(charAr[1]=='!') {
                for (int i = 0; i < 5; i++) {
                    if (i == value) continue;
                    result.add(i);
                }
            }else if(charAr[1]=='<'){
                for(int i=0;i<=value;i++){
                    result.add(i);
                }
            }else{
                for(int i=value;i<5;i++){
                    result.add(i);
                }
            }

        }else{
            int value=charAr[2]-'1';
            if(charAr[1]=='=') {
                result.add(value);
            }else if(charAr[1]=='<'){
                for(int i=0;i<value;i++){
                    result.add(i);
                }
            }else{
                for(int i=value+1;i<5;i++){
                    result.add(i);
                }
            }

        }
        return result;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值