题目传送门
题意: 有一堆二进制数(01串,按字典序排序),从0到2m-1 ,我们删除其中n(n<=100)个数,再输出这些数的中位数。
思路: 二进制的字典序排序其实和转化成十进制之后的顺序是一样的。我们先把删除了的数转化十进制,然后sort一下,因为最多删除100个数,我们把这一百个数当做分界,每次加一个分界,如果现在的总数大于我们找的中位数了,那中位数就在这个区间里。
代码:
#include<bits/stdc++.h>
#define endl '\n'
#define null NULL
#define ls p<<1
#define rs p<<1|1
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define ll long long
#define int long long
#define pii pair<int,int>
#define ull unsigned long long
#define all(x) x.begin(),x.end()
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ct cerr<<"Time elapsed:"<<1.0*clock()/CLOCKS_PER_SEC<<"s.\n";
char *fs,*ft,buf[1<<20];
#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
inline int read(){int x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();}
return x*f;}
using namespace std;
const int N=1e5+5;
const int inf=0x7fffffff;
const int mod=998244353;
const double eps=1e-6;
const double PI=acos(-1);
string s[105];int num[105];
ll qpow(ll a,ll b)
{
int res=1;
while(b)
{
if(b&1)
res=res*a;
a=a*a;
b>>=1;
}
return res;
}
signed main()
{
int t;
cin>>t;
while(t--)
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>s[i];
num[i]=0;
for(auto j:s[i])
{
num[i]=num[i]*2+(j-'0');
}
}
num[0]=-1;
sort(num+1,num+n+1);
int pos=(qpow(2,m)-n-1)/2;
pos++;
int tot=0,res=-1;
for(int i=1;i<=n;i++)
{
tot+=num[i]-num[i-1]-1;
if(tot>=pos)
{
tot-=num[i]-num[i-1]-1;
res=num[i-1]+pos-tot;
break;
}
}
if(res==-1)
{
res=num[n]+pos-tot;
}
stack<int>q;
while(res)
{
q.push(res%2);
res>>=1;
}
while(q.size()<m)
{
q.push(0);
}
while(!q.empty())
{
cout<<q.top();
q.pop();
}
cout<<endl;
}
}