• L2-052 吉利矩阵


    题目描述

    在这里插入图片描述

    题解思路

    这个道题就是很简单,就跟n皇后问题一样,给矩阵填数,使得矩阵满足一个什么条件,最后求方案数或者方案。很容易想到回溯法,根据数据范围,应该能够确定回溯法是没有问题的。
    我们只需要枚举矩阵的每一个位置,给这个位置填上一个数,如果满足条件,我们就枚举下一个位置。这里的满足条件是指,如果当前位置是某一行的最后一个位置或者某一列的最后一个位置,那么我们需要保证填上这个数之后当前行或列的数字之后等于L
    为了实现简单,我们使用xx[]来表示行的和,yy[]来表示列的和。枚举位置的时候我们使用像解八数码问题那样,使用一个数idx来枚举,idx/n就是横坐标,idx%n就是纵坐标,再加上一点剪枝就没有问题。

    代码实现

    Java

    Java超时了,真够离谱的

    import java.util.Scanner;
    
    public class Main {
    
        static int l, n, ans;
        static int[] xx = new int[5], yy = new int[5];
    
        public static void main(String[] args) {
            Scanner in = new Scanner(System.in);
            l = in.nextInt();
            n = in.nextInt();
            dfs(0);
            System.out.println(ans);
        }
    
        public static void dfs(int idx) {
            if (n * n == idx) {
                ans ++;
                return;
            }
            for (int i = 0; i <= l; i ++) {
                int x, y;
                x = idx / n;
                y = idx % n;
                if (xx[x] + i > l || yy[y] + i > l) continue;
                /**
                 * if (x == n - 1 && yy[y] + i < l) continue;
                 * if (y == n - 1 && xx[x] + i < l) continue;
                 * 本来以为是这里浪费时间了,
                 * 就改成下边那个,代码速度一定提高了,
                 * 但java还是超时, C/C++两个都可以过,下边的更快
                 */
                if (x == n - 1 ) i = l - yy[y];
                if (y == n - 1 ) i = l - xx[x];
                xx[x] += i;
                yy[y] += i;
                dfs(idx + 1);
                xx[x] -= i;
                yy[y] -= i;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    C/C++

    #include 
    using namespace std;
    int l, n, ans;
    int xx[5], yy[5];
    void dfs(int);
    int main() {
        cin >> l >> n;
        dfs(0);
        cout << ans;
        return 0;
    }
    void dfs(int idx) {
        if (n * n == idx) {
            ans ++;
            return;
        }
        for (int i = 0; i <= l; i ++) {
            int x, y;
            x = idx / n;
            y = idx % n;
            if (xx[x] + i > l || yy[y] + i > l) continue;
            if (x == n - 1 ) i = l - yy[y];// if (x == n - 1 && yy[y] + i < l) continue;本来是这个,但是我们可以直接让i等于我们需要的那个值。两种都可以过
            if (y == n - 1 ) i = l - xx[x];
            xx[x] += i;
            yy[y] += i;
            dfs(idx + 1);
            xx[x] -= i;
            yy[y] -= i;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
  • 相关阅读:
    【Rust日报】2022-08-29 RLS 谢幕
    Jmeter接口测试, 快速完成一个单接口请求
    Java面试题之接口和抽象类的区别
    一句话木马SQL注入
    Insertion or Heap Sort(堆排序解释)(PAT甲级)
    JavaScript小技能:客户端 API
    本次CTF·泰山杯网络安全的基础知识部分
    红黑树(C语言实现)
    硬核新品!M4E EDU民航考培一体无人机
    BAT大佬总结的《Java开发实战1200例》,所有项目均包含源码
  • 原文地址:https://blog.csdn.net/m0_62740234/article/details/138075450