UVA11127- Triple-Free Binary Strings(DFS+位运算)

题目链接

题意:给出长度为n的字符串,字符串由‘1’,‘0’,‘*’组成,其中‘*’可以任意替换为‘1’,‘0’,求不存在连续3个相同子串的字符串的最多个数。

思路:我们可以利用二进制的形式来表示字符串,进行DFS。利用位运算的左移来表示在‘*’位置上放置‘1’,注意在递归的过程中注意判断之否存在3个连续相同的子串。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int MAXN = 32;

char str[MAXN];
int n, ans;

bool judge(int s, int d) {
    int k = (1 << d) - 1;
    int a = s & k;
    s = s >> d;
    int b = s & k;
    s = s >> d;
    int c = s & k;
    if (a == b && b == c)
        return true;
    else
        return false;
}//利用位运算,右移d位,判断是否存在3个子串相同

void dfs(int s, int cnt) {
    int num = cnt / 3;
    int t = n - cnt - 1;
    for (int i = 1; i <= num; i++) {
        if (judge(s >> (t + 1), i))
            return;
    }
    if (cnt == n) {
        ans++;
        return;
    }
    else if (str[cnt] == '0') {
         dfs(s, cnt + 1);
    }
    else if (str[cnt] == '1') {
         dfs(s + (1 << t), cnt + 1);
    }
    else if (str[cnt] == '*') {
         dfs(s, cnt + 1);
         dfs(s + (1 << t), cnt + 1);
    }
    return;
}

int main() {
    int cas = 1;
    while (scanf("%d", &n) && n) {
        scanf("%s", str);
        ans = 0;
        dfs(0, 0);
        printf("Case %d: %d\n", cas++, ans);
    }
    return 0;
}

UVA11127- Triple-Free Binary Strings(DFS+位运算)

时间: 2024-10-08 23:50:06

UVA11127- Triple-Free Binary Strings(DFS+位运算)的相关文章

UVa 818Cutting Chains (暴力dfs+位运算+二进制法)

题意:有 n 个圆环,其中有一些已经扣在一起了,现在要打开尽量少的环,使所有的环可以组成一条链. 析:刚开始看的时候,确实是不会啊....现在有点思路,但是还是差一点,方法也不够好,最后还是参考了网上的题解,大神们的代码就是不一样, 但还是看了好久才看懂.首先是用二进制法进行暴力,因为 n 最大才是15,不会超时的,然后就是在暴力时判断打开这些环时,剩下的是不是还存在环, 如果存在那么不是不行的,然后再判断是不是有的环有两个分支以上,因为一个环如果成链那么最多只有两个分支,所以多于两个的也是不对

皇后问题(DFS)(位运算)

皇后问题 题目描述: 有一个n*n的棋盘,你要在这个棋盘上放上n个皇后,使得她们不能相互攻击.当然为了使得问题更加有趣,我们在棋盘上限定了一些位置使得这些位置上不能放皇后. 输入格式: 第一行两个数n和m ,表示在一个n*n的棋盘上放n个皇后,有m个受限位置. 接下来m行每行两个数,x和y,表示第x行,第y列这个位置不可以放皇后. 输出格式: 一行一个数 ans,表示总的方案数. 样例输入: 4 1 1 2 样例输出: 1 朴素算法(60分) #include<iostream> using

UVA - 11127 Triple-Free Binary Strings dfs

题目大意:有一个字符串,这个字符串由0,1和*组成,*可以变成0也可以变成1,要求变化后的字符串的字符只能是0或者1. 现在给出这个字符串,要求变化后的字符串中不能出现三个连续相同的子串,问最多可以变化成多少个符合规则的串 解题思路:因为只有0和1,且只有30位,所以可以用一个正数来表示状态.dfs暴力枚举,边枚举边判断,看当前的是否符合 #include<cstdio> #include<cstring> using namespace std; #define maxn 35

[CF792D] Paths in a Complete Binary Tree (规律, 位运算, lowbit)

题目链接:http://codeforces.com/problemset/problem/792/D 画出树,找找规律,画图就好了.不算麻烦. 往下走的时候特判是不是叶子,往上走的时候特判是不是根.其余时候按照规律转移就是. 感觉可以推广到建树上,可以缩小常数是极好的. 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 LL lowbit(LL x) { return x & (

N皇后问题(位运算实现)

本文参考Matrix67的位运算相关的博文. 顺道列出Matrix67的位运算及其使用技巧 (一) (二) (三) (四),很不错的文章,非常值得一看. 主要就其中的N皇后问题,给出C++位运算实现版本以及注释分析. 皇后问题很经典,就不再赘述问题本身,解决皇后问题,一般采用的都是深搜DFS+回溯的方法,按照行(列)的顺序枚举每一个可以放置的情况,然后进行冲突判断,当前的放置是否合法,合法就继续搜索下一层,不合法就搜索就回溯.直到,找到一个合法的解,每一层都有一个皇后并且不发生冲突,这时候,放置

476. Number Complement【位运算】

2017/3/14 15:36:44 Given a positive integer, output its complement number. The complement strategy is to flip the bits of its binary representation. Note: The given integer is guaranteed to fit within the range of a 32-bit signed integer. You could a

使用位运算显示二进制数

最近学习<C Primer Plus>位操作部分,结合书上的编程实例来巩固这部分知识点. 1 //使用位运算显示二进制数 2 #include<stdio.h> 3 char *itobs( int, char*); //integer to binary string 4 void show_bstr( const char*); 5 main() 6 { 7 char bin_str[8 * sizeof(int) +1]; 8 int number; 9 while(scan

Java 位运算

一,Java 位运算 1.表示方法: 在Java语言中,二进制数使用补码表示,最高位为符号位,正数的符号位为0,负数为1.补码的表示需要满足如下要求. (l)正数的最高位为0,其余各位代表数值本身(二进制数). (2)对于负数,通过对该数绝对值的补码按位取反,再对整个数加1. 2.位运算符 位运算表达式由操作数和位运算符组成,实现对整数类型的二进制数进行位运算.位运算符可以分为逻辑运算符(包括~.&.|和^)及移位运算符(包括>>.<<和>>>). 1)左

位运算+枚举

位运算http://c.biancheng.net/cpp/html/101.html 在很多情况下(比如翻棋子)在搜索时涉及大量枚举往往导致超时,位运算则很好地解决了这个问题,方便又快捷 HDU  1882   Strange Billboard http://acm.hdu.edu.cn/showproblem.php?pid=1882 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot