2020-2021年度第二届全国大学生算法设计与编程挑战赛(冬季赛)——正式赛(Java语言题目解析)

本文详细解析了第二届全国大学生算法设计与编程挑战赛的热身赛和正式赛部分,包括排列巨人、三子棋、钻石等题目的解题思路,涉及全排列计算、棋盘问题、贪心策略等算法思想。
摘要由CSDN通过智能技术生成

附上这些题目的链接

这是热身赛

排列巨人

题目描述:

有12个数字,分别是1~12。
计算并输出这12个数字的全排列的种类数。

解题思路:
由题意知:题目实际要求1~12全排列的种类数。
由简单的数学知识我们知道:1~12的全排列的种类数为 12 !

package content;/**
 * Copyright (C), 2019-2021
 * author  candy_chen
 * date   2021/3/1 17:10
 *
 * @Classname test
 * Description: 算法竞赛:排列巨人
 */

/**
 *
 */
public class Tester_01{
   
    public static void main(String[] args){
   
        int n = 12;
        int count = n * f(n - 1);
        System.out.print("对于12名巨人的排列方式有" + count +"种:" );

        int[] buf = {
   1,2,3,4,5,6,7,8,9,10,11,12};
        prem(buf,0,buf.length - 1);


        return;
    }

    private static void prem(int[] buf, int start, int end) {
   
        int count = 12;
        if(start==end){
   //输出排列好的数组
            System.out.print("{");
            for(int c:buf){
   
                System.out.print(c);
                if (count > 1){
   
                    System.out.print(",");
                    count--;
                }

            }
            System.out.print("}");
            System.out.print("、");
        }else{
   
            for(int i=start;i<=end;i++){
   
                int temp=buf[start];//前后元素交换
                buf[start]=buf[i];
                buf[i]=temp;

                prem(buf,start+1,end);//递归交换后面的元素

                temp=buf[start];
                buf[start]=buf[i];
                buf[i]=temp;

            }
        }
    }

    private static int f(int i) {
   

        int count = 1;
        if (i > 0){
   
            count  = i *  f(i - 1) ;
        }
        return count;
    }

}

三子棋

在这里插入图片描述
解题思路:

数据范围很小,可以O(S*T)枚举每一个位置的棋子。
接着判断这个棋子是否是横着、竖着、斜着(左上到右下、右上到左下两个方向)能够构成三连子。
如果可以,那么这个格子的棋子就是答案,直接输出即可。
全部棋子枚举完没有找到三连子,意味着平局,输出ADPC! 注意叹号是英文叹号

mp[i][j]为第i行第j列的格子上的棋子或无人下棋
	第i行为:从上到下的第i行
	第j列为:从左到右的第j列
在枚举过程中,设当前棋子为mp[i][j]
则左边挨着的棋子所在的列即为mp[i][j-1]、右边为mp[i][j+1]
判断三者是否相等即可完成横着方向的判断。
之后在竖、斜方向的判断仍然同理。
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.io.Closeable;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;
import java.util.Scanner;

//判断是否连成三子棋,可以枚举棋盘上每一个位置的棋子。
//接着判断这个棋子是否是横着、竖着、斜着(左上到右下、右上到左下两个方向)能够构成三连子,
//如果可以,那么这个格子的棋子就是答案,直接输出即可。
//全部棋子枚举完没有找到三连子,意味着平局,输出ADPC!    注意叹号是英文叹号
//

public class Main {
   
    public static void main(String [] args) {
   
        Scanner in  = new Scanner(System.in);
        int s = in.nextInt();
        int t = in.nextInt();// 输入棋盘的行和列
        char mp[][] = new char[33][33];
        //mp[i][j]为第i行第j列的格子上的棋子或无人下棋
        //第i行为:从上到下的第i行
        //第j列为:从左到右的第j列
        String str;
        for(int i = 1; i <= s; i++) {
   
            str = in.next();
            for(int j = 1; j <= t; j++) {
   
                mp[i][j] = str.charAt(j - 1);
            }
        }

        for(int i = 1; i <= s; i++) {
   
            for(int j = 1; j <= t; j++) {
   
                //判断当前棋子为中心的横着三个棋子是否构成三子棋,即当前棋子和它左右两棋子是否相同
                if(mp[i][j-1]==mp[i][j]&&mp[i][j]==mp[i]j+1]&&mp[i][j]!='.'){
   
                    System.out.println(mp[i][j]);//此时连成三子棋,输出此位置字符即为答案
                    return ;//return 0执行,程序结束。
                }
                //判断当前棋子为中心的竖着三个棋子是否构成三子棋,即当前棋子和它上下两棋子是否相同
                if(mp[i-1][j]==mp[i][j]&&mp[i][j]==mp[i+1][j]&&mp[i][j]!='.'){
   
                    System.out.println(mp[i][j]);//此时连成三子棋,输出此位置字符即为答案
                    return ;//return 0执行,程序结束。
                }
                //判断当前棋子为中心的斜着(左上到右下)三个棋子是否构成三子棋,即当前棋子和它左上、右下两棋子是否相同
                if(mp[i-1][j-1]==mp[i][j]&&mp[i][j]==mp[i+1][j+1]&&mp[i][j]!='.'){
   
                    System.out.println(mp[i][j]);//此时连成三子棋,输出此位置字符即为答案
                    return ;//return 0执行,程序结束。
                }
                //判断当前棋子为中心的斜着(右上到左下)三个棋子是否构成三子棋,即当前棋子和它右上、左下两棋子是否相同
                if(mp[i-1][j+1]==mp[i][j]&&mp[i][j]==mp[i+1][j-1]&&mp[i
  • 5
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值