H. Binary Median (贪心)

传送门

思路:因为要找到去除 n n n个字符串后第 k − 1 2 \dfrac{k-1}{2} 2k1小的字符串。

考虑在不去除任何字符串的时候第 k − 1 2 \dfrac{k-1}{2} 2k1小的字符串转为十进制答案就是 p o s = k − 1 2 pos=\dfrac{k-1}{2} pos=2k1

因为是去除 n n n个字符串,所以 p o s pos pos只能向右移动。

这里只需要对 n n n个字符串转换为十进制从小到大进行排序,然后如果有 a [ i ] ≤ p o s , p o s a[i]\leq pos,pos a[i]pos,pos就右移动一位。这里从小到大排序是防止 p o s pos pos移动到删掉的字符串位置。 e p : p o s 0 = 5 , a 1 = 6 , a 2 = 5 ep: pos_0=5, a_1=6,a_2=5 ep:pos0=5,a1=6,a2=5这里 p o s pos pos移动到6就停了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
#define mst(a) memset(a,0,sizeof a)
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		ll n,m,k;
		scanf("%lld%lld",&n,&m);
		k=(1LL<<m)-n-1,k/=2;
		ll a[105]={},ans[105]={};
		char b[65];
		for(int i=0;i<n;i++){
			scanf("%s",b);
			for(int j=0;j<m;j++)
			  a[i]=a[i]*2+b[j]-'0';
		}
		sort(a,a+n);
		for(int i=0;i<n;i++)
			if(a[i]<=k) k++;
		for(int i=0;i<m;i++)
			  ans[i]=k%2,k/=2;
		for(int i=m-1;i>=0;i--) printf("%d",ans[i]);
		puts(""); 
	}
	return 0;
}