zoukankan      html  css  js  c++  java
  • CF 1469E A Bit Similar

    抄完韩教代码感觉自己本来也应该想出这种方法的。。。

    这道题搁置了有一段时间了

    总结一下

    本题给出字符串s,要求在其中截取长度为k的01串共n-k+1个,问能不能找出一个字典序最小的、长度也为k的01串,使得这个结果串与n-k+1中每一个串至少有一位相同。

    其实答案也挺暴力的,但也有一定的特殊性。对于这n-k+1个串,如果题目中k的大小满足2 ^ k > n - k + 1则必定有解。

    可以看出,如果我们把这长度为k的串以10进制形式表达,那么它的个数必定小于等于k位二进制数的个数,即2 ^ k个。因而严格大于才保证有解。

    根据这一特性,因为题目中k <= 1e6,那么实际上n - k + 1也是近似1e6的规模,因而当k取到20就能解决本题的所有情况了。

    对于k > 20的时候,我们需要补上前导0。

    而对于其他情况,我们需要开个标记数组,将每个串的有效位(<=20)转为10进制加以标记,然后for一遍看有没有合法的。

    如果有,我们补上前导0后再以二进制输出这个数就好了。如果没有就是NO。

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 const int N = 1e6 + 10;
     5 
     6 int sum[N], vis[N << 1];
     7 
     8 int main(){
     9     ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    10     int t; cin >> t;
    11     while(t--)
    12     {
    13         int n, k; cin >> n >> k;
    14         string s; cin >> s;
    15         for(int i = 1 ; i <= n ; i++){
    16             sum[i] = sum[i - 1] + (s[i - 1] == '0');
    17         }
    18         int cnt = n - k + 1;
    19         int bit;
    20         for(int i = 20 ; i >= 0 ; i--){
    21             if(cnt & (1 << i)){
    22                 bit = i + 1;//多取一位,保证2 ^ bit > n - k + 1
    23                 break;
    24             }
    25         }
    26         bit = min(bit, k);
    27         for(int i = 0 ; i <= n * 2 ; i++){//标记数组重置
    28             vis[i] = 0;
    29         }
    30         
    31         for(int i = n - bit + 1 ; i >= k - bit + 1 ; i--){//对于每个长为k的串,只看它的后bit位,i是串的头 
    32             if(sum[i - 1] - sum[i - (k - bit) - 1])    continue;
    33             int now = 0;
    34             for(int j = i + bit - 1 ; j >= i ; j--){//j是串的尾巴,从后向前处理 
    35                 if(s[j - 1] == '0'){
    36                     now |= (1 << (i + bit - 1 - j));//把反着的标记,也即遇到0就在这一位或上1
    37                 }
    38             }
    39             vis[now] = 1;
    40         }
    41         
    42         int tag = 0;
    43         for(int i = 0 ; i < (1 << bit) ; i++){
    44             if(!vis[i]){//当前数字没有被标记过 
    45                 tag = 1;
    46                 cout << "YES" << endl;
    47                 for(int j = 1 ; j <= k - bit ; j++){
    48                     cout << "0";
    49                 }//k - b个0
    50                 for(int j = bit - 1 ; j >= 0 ; j--){
    51                     if(i & (1 << j)){
    52                         cout << "1";
    53                     }else{
    54                         cout << "0";
    55                     }
    56                 }
    57                 cout << endl;
    58                 break;
    59             }
    60         }
    61         if(!tag)    cout << "NO" << endl;
    62     }
    63 
    64     return 0;
    65 }
  • 相关阅读:
    【转】VB 技巧一
    VB中的trim()函数
    转:vb实现老板键功能
    VB为自己的程序设定消息(可接收处理)
    RegisterHotKey的具体使用方法
    GetPrivateProfileString
    在VB语言中,DOEVENTS的具体的用法和含义
    VB中的ADO数据对象编程
    jquery操作select下拉列表框
    jQuery对Select的操作集合
  • 原文地址:https://www.cnblogs.com/ecustlegendn324/p/14264928.html
Copyright © 2011-2022 走看看