zoukankan      html  css  js  c++  java
  • 倪文迪带你学蓝桥杯2021寒假每日一题:1.6日第4题,C++、Java、Python三种代码

    2021年寒假每日一题,2017~2019年的省赛真题。
    本文内容由倪文迪(华东理工大学计算机系软件192班)和罗勇军老师提供。

    @

    题目:方格分割 http://oj.ecustacm.cn/problem.php?id=1320
      2017年蓝桥杯软件类省赛C++语言大学A组第4题,一道填空题。

    1、题目大意

      6x6的方格,沿着格子的边线剪开成两部分。要求这两部分的形状完全相同。
      试计算:一共有多少种不同的分割方法。注意:旋转对称的属于同一种分割法。

    2、题解

      又是暴搜。第1题DFS,第2题BFS,第3题BFS,这题又回到DFS。下一题估计是BFS?
      
      倪文迪的话:“这道题可能上来会想到搜格子,但搜格子意味着更高的复杂度以及判连通的需要,本题似乎搜索要切开的边更优。由题意,这一条切割线必定经过图的中心点,那么我们一旦确定了半条到达边界的分割线,就能根据这半条对称画出另外半条。而由于结果中心对称性,搜索出来的个数应该除以4得出最终结论。在搜索过程中需要注意的是,我们搜索出的半条分割线不能同时经过关于中心对称的两个点,所以在标记时,需要将对称的点也标上。”
      中心点是(3,3),从(3,3)出发,向右、向左、向上、向下,四个方向DFS即可。
      
      下面给出三种语言的代码。
      据说Python组参加人少,容易得奖。Python真是好,Python呱呱叫。

    3、C++代码

    倪文迪的代码:

    #include<bits/stdc++.h>
    using namespace std;
    
    int X[] = {0, -1, 1, 0, 0};
    int Y[] = {0, 0, 0, -1, 1};
    
    bool vis[10][10];
    int res = 0;
    
    void dfs(int x, int y)
    {
    	if(x == 0 || y == 0 || x == 6 || y == 6){
    		res++;
    		return ;
    	}
    	for(int i = 1 ; i <= 4 ; i++){   //上下左右四个方向
    		x += X[i]; y += Y[i];        //走一步
    		if(!vis[x][y]){       // 若该点未访问则继续深搜
    			vis[x][y] = true;  //  当前的点标注为已访问
    			vis[6 - x][6 - y] = true;
    			dfs(x, y);         // 继续深搜
    			vis[6 - x][6 - y] = false;
    			vis[x][y] = false;
    		}
    		x -= X[i]; y -= Y[i];
    	}
    }
    
    int main(){
    	vis[3][3] = true;
    	dfs(3, 3);
    	cout << res / 4 << endl;
    
    	return 0;
    }
    
    

    4、Java代码

    http://oj.ecustacm.cn/用户20185012的代码:

    public class Main {
     
        private static int ans = 0;
        private static int[][] dir = {{1,0},{-1,0},{0,1},{0,-1}};
        private static boolean[][] visit = new boolean[7][7];
     
        public static void main(String[] args) {
            visit[3][3] = true;
            dfs(3,3);
            System.out.println(ans / 4);
        }
     
        private static void dfs(int x,int y){
            if (x == 0 || y == 0 || x == 6 || y == 6){
                ans ++;
                return;
            }
            visit[x][y] = true;
            visit[6 - x][6 - y] = true;
            for (int i = 0; i < 4; i++) {
                int nx = x + dir[i][0];
                int ny = y + dir[i][1];
                if (nx < 0 || nx > 6 || ny < 0 || ny > 6)
                    continue;
                if (!visit[nx][ny])
                    dfs(nx,ny);
            }
     
            visit[x][y] = false;
            visit[6 - x][6 - y] = false;
        }
    }
    

    5、Python代码

    http://oj.ecustacm.cn/用户20192031003的代码:

    count = 0
    vis = [[1] * 7 for i in range(7)]
    dir = [(-1, 0), (1, 0), (0, -1), (0, 1)]
     
     
    def dfs(x, y):
        global count
        if x == 0 or y == 0 or x == 6 or y == 6:
            count += 1
            return
        # 当前点和对称点都标注访问
        vis[x][y], vis[6 - x][6 - y] = 0, 0
        for i in range(0, 4):
            # 新坐标
            newx = x + dir[i][0]
            newy = y + dir[i][1]
            if newx < 0 or newx > 6 or newy < 0 or newy > 6:
                continue
            if vis[newx][newy]:
                dfs(newx, newy)
        vis[x][y], vis[6 - x][6 - y] = 1, 1
     
     
    dfs(3, 3)
    print(count//4)
    
  • 相关阅读:
    SQL Server 2005中的分区表(六):将已分区表转换成普通表
    关于SQL Server中分区表的文件与文件组的删除(转)
    MySQL修改root密码的几种方法
    Aptana 插件 for Eclipse 4.4
    IT励志与指导文章合集(链接)
    正则表达式(转)
    《疯狂原始人》温馨而搞笑片段截图
    指针函数与函数指针的区别(转)
    Linux内核@系统组成与内核配置编译
    2015年我国IT行业发展趋势分析(转)
  • 原文地址:https://www.cnblogs.com/luoyj/p/14241723.html
Copyright © 2011-2022 走看看