1 条题解

  • 1
    @ 2025-7-25 10:54:12
    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N = 11;
    const int inf = 0x3f3f3f3f;
    const int g[4][2] = {{1 , 0} , {-1 , 0} , {0 , 1} , {0 , -1}};
    bool vis[N][N];
    int n;
    //剪枝方案:
    //1. 判断邻居点是否是死胡同,是则必须走到那个点
    //
    //即 
    
    //     *
    //  *  0  *
    
    //必须先走到 0
     
    // *为走过,0为未走过 
    
    //2. 终点的上与右两个点是否被走过,且步数>=n-2
    
    //即 
    
    //   *
    //   #  * 
    
    //*为走过,#为终点 
    
    //3.当未走点在两走过点之间 
    //即
    
    //
    //*  0  *
    //
    
    //或
    
    //  *
    //  0
    //  *
    
    //*为走过,0为未走过 
    
    bool check(int x , int y){//边界范围 
    	return x >= 1 && x <= n && y >= 1 && y <= n; 
    }
    
    bool q = false;
    bool ch(int x , int y){//判断邻居点是否是死胡同 
    	int sum = 0;
    	for(int i = 0 ; i < 4 ; i ++){
    		int tx = x + g[i][0];
    		int ty = y + g[i][1];
    		if(vis[tx][ty] && check(tx , ty)){
    			sum ++;
    		}else if(!check(tx , ty) && !q){
    			sum += 1;
    			q = true;//边界点只能算1个 
    		}
    	}
    	if(sum >= 3){//被包围 
    		return true;
    	}else{
    		return false;
    	}
    }
    
    int ans = 0;
    
    void dfs(int x , int y , int sum){//sum表示走过的点数 
    //	cout << x << " " << y << " " << sum << endl;
    
    	if(vis[n - 1][1] && vis[n][2] && sum <= n * n - 2){//终点的上与右两个点是否被走过,且步数>=n-2 
    		return;
    	}
    	 
    	//出口 
    	if(x == n && y == 1){//到终点 
    		if(sum == n * n){//走完所有点 
    			ans ++;	
    		}
    		return;
    	}
    	
    	// 当未走点在两走过点之间 
    	if(
    		vis[x - 1][y] && 
    		vis[x + 1][y] && 
    		!vis[x][y + 1] && 
    		!vis[x][y - 1]
    		){
    		return;
    	}
    	if(
    		!vis[x - 1][y] && 
    		!vis[x + 1][y] &&
    		vis[x][y + 1] && 
    		vis[x][y - 1]
    		){
    		return;
    	}
    	
    	for(int i = 0 ; i < 4 ; i ++){
    		int tx = x + g[i][0];
    		int ty = y + g[i][1]; 
    		
    		if(ch(tx , ty) && check(tx , ty) && !vis[tx][ty]){// 判断邻居点是否是死胡同,是则必须走到那个点
    			vis[tx][ty] = true;
    			dfs(tx , ty , sum + 1);
    			vis[tx][ty] = false;
    			break;
    			
    		}else if(check(tx , ty) && !vis[tx][ty]){
    			vis[tx][ty] = true;
    			dfs(tx , ty , sum + 1);
    			vis[tx][ty] = false;
    		}
    	}
    }
    
    signed main(){
    	freopen("Betsy.in" , "r" , stdin);
    	freopen("Betsy.out" , "w" , stdout);
    	cin >> n;
    	vis[1][1] = true;
    	if(n == 1){
    		cout << 1;
    		return 0;
    	}else if(n == 2){
    		cout << 1;
    		return 0;
    	}else{
    		//将边界点初始为T
    		 
    		for(int i = 1 ; i <= n ; i ++){
    			vis[0][i] = vis[n + 1][i] = true;
    		}
    		for(int i = 1 ; i <= n ; i ++){
    			vis[i][0] = vis[i][n + 1] = true;
    		}
    		
    		dfs(1 , 1 , 1);
    	}
    	cout << ans;
    	return 0;
    }
    

    信息

    ID
    554
    时间
    2000ms
    内存
    256MiB
    难度
    9
    标签
    (无)
    递交数
    216
    已通过
    13
    上传者