[블루 브릿지 컵] 2013 년 C ++ A 그룹 문제 9 시험 교육

격자 컷 

그림에서 빨간색 선을 따라 잘라서 두 부분을 얻었습니다. 각 부분의 숫자의 합은 60입니다.

이 질문의 요구 사항은 주어진 mxn 그리드의 정수를 두 부분으로 나눌 수 있는지 여부를 결정하도록 프로그래밍하여 두 영역의 숫자 합계가 동일하도록 요청하는 것입니다.
여러 솔루션이있는 경우 왼쪽 상단 그리드를 포함하는 영역에 포함 된 최소 그리드 수를 출력하십시오.   
나눌 수없는 경우 0이 출력됩니다.

프로그램 입력 및 출력 형식 요구 사항 :
프로그램은 먼저
테이블의 너비와 높이 나타 내기 위해 공백 (m, n <10)으로 구분 된 두 개의 정수 mn을 읽습니다 .
다음은 각각 공백으로 구분 된 m 개의 양의 정수가있는 n 개의 행입니다. 각 정수는 10000보다 크지 않습니다
. 프로그램 출력 : 모든 솔루션에서 왼쪽 상단 모서리의 파티션 영역에 포함될 수있는 가장 작은 그리드 수입니다.

예 :
사용자 입력 :
3 3
10 1 52
20 30 1
1 2 3

프로그램 출력 :
3

다른 예 :
사용자 입력 :
4 3
1 1 1
1 30 80 2
1 1 1100

프로그램 출력 :
10

 

문제 분석 :

재귀 + 역 추적 + 가지 치기

아이디어 : 그리드에서 심층 검색을 수행하기 위해 재귀를 사용하고 변경 상태는 각 시간의 좌표 및 레코드의 합계입니다. 카운트는 수행 한 단계 수를 기록하는 데 사용됩니다. 그리드의 총 값이 모든 합계를 초과합니다. 시간의 절반이 될 때 직접 반환 될 수 있으며 전체가 합계의 절반과 같을 때 이번에 절반에 도달 한 단계 수가 가장 작은 지 비교해야합니다. 이전 단계와 비교하여 동일한 상태의 재귀 호출은 각 단계가 4 개라는 것입니다. 4 개의 방향에 대해 4 개의 방향의 격자를 재귀 적으로 호출하고 판단 조건도주의해야합니다.

일반적 으로 그래프 순회를 위해서는 원래 경로를 반복 할 수 없다는 점을 고려하여 (순회를 반복 할 수없는 경우) 주소 방문 여부를 기록하기 위해 다른 공간을 신청해야합니다. 즉, vis 배열이 다시 열리고 vis 배열은 방문하지 않습니다. 방문한 항목은 0이고 방문한 항목은 1입니다.

#include <iostream>
#include <algorithm>
using namespace std;

int m, n;
int g[10][10];
int vis[10][10];	//记录走过的状态 
int total;
int res = 1000;
int count;

void f(int i, int j, int sum, int count){	//变化状态 ->参数 
	//边界,出口条件,当sum和大于总的一半时可以返回 
	if(sum > total / 2){
		return ;
	} 
	if(sum == total / 2){	//当sum 等于总的一半时,可以剪了,那么把这里 
		res = min(res, count);
		return; 
	}
	
	vis[i][j] = 1; //该格子被访问过了 
	
	//下一步的四个分支
	if(i+1 <= n-1 && vis[i+1][j] == 0){		//保证下一步的格子没有走过	
		f(i+1, j, sum+g[i][j], count+1);
	}
	if(i-1 >= 0 && vis[i-1][j] == 0){
		f(i-1, j, sum+g[i][j], count+1);
	}
	if(j+1 <= m-1 && vis[i][j+1] == 0){
		f(i, j+1, sum+g[i][j], count+1);
	}
	if(j-1 >= 0 && vis[i][j-1] == 0){
		f(i, j-1, sum+g[i][j], count+1);
	}
	
	vis[i][j] = 0; 
} 

int main(int argc, char** argv) {
	cin >> m >> n;	
	
	for(int i = 0; i < n; i++){
		for(int j = 0; j < m; j++){
			cin >> g[i][j];
			total += g[i][j];
		}
	} 
	
	f(0, 0, 0, 0);
	
	if(res != 1000){
		cout << res;
	}else{
		cout << "0";
	}
	
	return 0;
}

 

추천

출처blog.csdn.net/weixin_44566432/article/details/115178585