H. Binary Median(思维,二进制)

题目传送门

题意: 有一堆二进制数(01串,按字典序排序),从0到2m-1 ,我们删除其中n(n<=100)个数,再输出这些数的中位数。

思路: 二进制的字典序排序其实和转化成十进制之后的顺序是一样的。我们先把删除了的数转化十进制,然后sort一下,因为最多删除100个数,我们把这一百个数当做分界,每次加一个分界,如果现在的总数大于我们找的中位数了,那中位数就在这个区间里。

代码:

#include
#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
#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;
    }
}

你可能感兴趣的:(数学,贪心,构造等思维问题)