1. 程式人生 > 實用技巧 >2019 藍橋杯省賽 B 組模擬賽 結果填空:馬的管轄

2019 藍橋杯省賽 B 組模擬賽 結果填空:馬的管轄

題意

每匹馬在不蹩腳的情況下能跳到的地方就是該馬能管轄的範圍,問在5*5的格子下至少需要多少匹馬能管轄到所有格子。

思路

二進位制列舉每一種情況,分開討論。

#include<bits/stdc++.h>

using namespace std;
int n,m;
int g[6][6],vis[6][6];
int dx[8]={-2,-1,2,1,-2,1,2,-1};
int dy[8]={-1,-2,-1,2,1,-2,1,2};
int fx[4]={-1,0,1,0};
int fy[4]={0,-1,0,1};

bool check(int x,int y){
	if(x>=0&&x<n&&y>=0&&y<m) return 1;
	else return 0;
}

int main(){
	n=5,m=5;
	int r=n*m;
	int res=0;//馬的數量
	int cnt=0;//覆蓋的格子數量
	int minn=25;//馬最小數量 
	int ans=0;//方案數 
	for(int i=0;i<(1<<r);i++){//列舉方案數 
		res=cnt=0;
		memset(g,0,sizeof(g));
		memset(vis,0,sizeof(vis));
		for(int j=0;j<r;j++){//遍歷二進位制的每一位 
			if(i&(1<<j)){//判斷該位是否存在 
				g[j/n][j%m]=1;
				vis[j/n][j%m]=1;
				res++;cnt++;
			}
		}
		if(res>minn) continue; 
		for(int j=0;j<n;j++){
			for(int k=0;k<m;k++){
				if(g[j][k]){
					for(int kk=0;kk<4;kk++){
						int mx=j+fx[kk];
						int my=k+fy[kk];
						if(check(mx,my)&&!g[mx][my]){//判斷是否蹩腳 
							for(int h=kk;h<8;h+=4){
								int nx=j+dx[h];
								int ny=k+dy[h];
								if(check(nx,ny)&&!vis[nx][ny]) {//不蹩腳馬覆蓋的範圍 
									vis[nx][ny]=1;
									cnt++; 
								}
							}
						}
					}
				}
			}
		}
		if(cnt!=25) continue;
		else {
			if(res<minn){
				minn=res;
				ans=1;
			} 
			else if(res==minn) ans++;
		}
	} 
	cout<<minn<<' '<<ans<<'\n';
	
	
	return 0;
}