列表

详情


NC25718. Bamboo Rat

描述

    In recent time, Hua Nong brothers' bamboo rat videos go viral and they have been Internet celebrities ever since then. As an investor, Boss Niu decides to build a breeding base to culture bamboo rats. 
    The breeding base can be described as a matrix, each cell of which contains a bamboo rat. Generally, every bamboo rat has a weight w.
    Today, Brother Wang comes to visit Boss Niu. Thus Boss Niu will select exactly k pretty bamboo rats to roast. In order not to make breeding base look so empty, Boss Niu can't select two adjacent bamboo rats. That is to say, if there are two bamboo rats sharing the same edge, he just can select one at most. Among k bamboo rats he selects, Boss Niu wants the weight of the lightest bamboo rat maximum. Please tell him the maximum weight of the lightest one.

输入描述

    The first line contains an integer number T, the number of test cases.
    For each test case:
    The first line contains three integers n, m, k(), the size of matrix and the number Boss Niu need to select.
    The following n lines, each contains m integers (), the weight of bamboo rats.

输出描述

For each test case print the answer.

示例1

输入:

2
2 2 2
4 3
3 2
3 3 4
3 7 8
4 9 6
7 4 2

输出:

3
4

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 87ms, 内存消耗: 492K, 提交时间: 2019-05-12 16:56:21

#include<bits/stdc++.h>
using namespace std;
using LL = long long;
constexpr int maxn = 1000;
int w[maxn], sw[maxn], f[maxn];
vector<int> G[maxn];
bool b[maxn];
bool find(int u){
	for(int v : G[u]) if(not b[v]){
		b[v] = true;
		if(f[v] == - 1 or find(f[v]))return f[v] = u, true;
	}
	return false; 
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int T;
	for(cin >> T; T; T -= 1){
		int n, m, k;
		cin >> n >> m >> k;
		for(int i = 0; i < n * m; i += 1){
			cin >> w[i];
			sw[i] = w[i];
		}
		sort(sw, sw + n * m);
		int L = 0, R = n * m;
		while(L + 1 < R){
			int M = sw[(L + R) >> 1], ans = 0;
			for(int i = 0; i < n * m; i += 1){
				G[i].clear();
				if(w[i] >= M) ans += 1;
				f[i] = -1;
			}
			for(int i = 0; i < n; i += 1)
				for(int j = 0; j < m; j += 1)
					if((i + j) % 2 == 0 and w[i * m + j] >= M){
						if(i > 0 and w[(i - 1) * m + j] >= M) G[i * m + j].push_back((i - 1) * m + j);
						if(i + 1 < n and w[(i + 1) * m + j] >= M) G[i * m + j].push_back((i + 1) * m + j);
						if(j > 0 and w[i * m + j - 1] >= M) G[i * m + j].push_back(i * m + j - 1);
						if(j + 1 < m and w[i * m + j + 1] >= M) G[i * m + j].push_back(i * m + j + 1);
					}
			for(int i = 0; i < n; i += 1)
				for(int j = 0; j < m; j += 1)
					if((i + j) % 2 == 0 and w[i * m + j] >= M){
						fill(b, b + n * m, false);
						if(find(i * m + j)) ans -= 1;
					}
			if(ans >= k) L = (L + R) >> 1;
			else R = (L + R) >> 1;
		}
		cout << sw[L] << "\n";
	}
	return 0;
}

C++14(g++5.4) 解法, 执行用时: 76ms, 内存消耗: 612K, 提交时间: 2019-05-15 20:30:35

#include<cstdio>
#include<vector>
using namespace std;
const int maxn = 1e3+9;
int n, m;
vector<int>e[maxn];
int f[maxn], a[maxn][maxn];
bool b[maxn];
int dx[]={0, 0, -1, 1};
int dy[]={-1, 1, 0, 0};
bool find(int u){
	for(int i=0; i<e[u].size(); ++i){
		int v=e[u][i];
		if(b[v]){
			continue;
		} 
		b[v]=true;
		if(-1==f[v]||find(f[v])){
			f[v]=u;
			return true;
		}
	}
	return false;
}
bool is_in(int x, int y){
	return 0<=x&&x<n&&0<=y&&y<m;
}
bool ok(int mid, int need){
	for(int i=0; i<n*m; ++i){
		e[i].clear();
		f[i]=-1;
	}
	int ans=0;
	for(int i=0; i<n; ++i){
		for(int j=0; j<m; ++j){
			if(a[i][j]>=mid){
				++ans;
			}
			if(a[i][j]>=mid&&(i+j)%2){
				int cd=i*m+j;
				for(int k=0; k<4; ++k){
					int nx=i+dx[k], ny=j+dy[k];
					if(is_in(nx, ny)&&a[nx][ny]>=mid){
						e[cd].push_back(nx*m+ny);
					}
				}
			}
		}
	}
	for(int i=0; i<n; ++i){
		for(int j=0; j<m; ++j){
			if(a[i][j]>=mid&&(i+j)%2){
				for(int k=0; k<n*m; ++k){
					b[k]=false;
				}
				if(find(i*m+j)){
					--ans;
				}
			}
		}
	}
	return ans>=need;
}
void solve(){
	int k;
	scanf("%d%d%d", &n, &m, &k);
	int L=1009, R=0;
	for(int i=0; i<n; ++i){
		for(int j=0; j<m; ++j){
			scanf("%d", &a[i][j]);
			L=min(L, a[i][j]);
			R=max(R, a[i][j]);
		}
	}
	while(L<R){
		int mid=(L+R+1)/2;
		if(ok(mid, k)){
			L=mid;
		}
		else{
			R=mid-1;
		}
	}
	printf("%d\n", L);
	
}
int main(){
	int T;
	scanf("%d", &T);
	while(T--){
		solve();
	}
	return 0;
} 

上一题