1080: [SCOI2008]劣质编码

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 337  Solved: 148
[Submit][Status][Discuss]

Description

  一个编码方案把每个字符对应到一个01串。例如{1,1010,01,10101}就是一个编码方案,它把四个字符(假设
它们为a,b,c,d)分别对应到串1、1010,01,10101。字符串的编码为各字符编码的连接。例如,在刚才的编码方
案中,字符串cac的编码为01101,dcb的编码为10101011010。 进一步分析发现,刚才的编码是相当劣质的,因为
字符串ba, acc和d的编码都是10101。对于一个编码方案,你的任务是找出三个不同的字符串,使得它们的编码全
相同。换句话说,找一个01编码串,使得它至少有三种解码方式。如果有多组解,这个编码串应当尽量短。

Input

  第一行包含一个整数n,即符号的个数。以下n行每行为一个长度不超过50的01串(可能为空串),即各符号的
编码。

Output

  仅一行,包含一个整数,即最短编码的长度。如果无解,输出-1。

Sample Input

4
1
1010
01
10101

Sample Output

5
 
 
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<string>
#include<map>
using namespace std;
typedef vector<int> ve;
map<ve,int>hash;
queue<ve>Q;
string s[];
int n;
void work(){
    ve u,v,t;
    for(int i=;i<=n;++i)
    if(s[i]=="") {puts("");exit();}
    else u.push_back(i<<);
    hash[u]=;
    Q.push(u);
    while(!Q.empty()){
        u=Q.front();
        Q.pop();
        int x=hash[u],cnt;
        for(int ch='';ch<='';++ch){
            cnt=;
            v.clear();
            for(int i=;i<(int)u.size();++i){
                int which=u[i]>>,where=u[i]&;
                if(s[which][where]^ch) continue;
                if(++where==s[which].size()) {
                    ++cnt;
                    for(int j=;j<=n;++j) v.push_back(j<<);
                }
                else v.push_back(which<<|where);
            }
            if(cnt>=) {printf("%d\n",x+);exit();}
            sort(v.begin(),v.end());
            t.clear();
            for(int i=;i<v.size();++i)
                if(i<||v[i]^v[i-]) t.push_back(v[i]);     //必须是i<m(m>=2)的形式,因为题干要求3个即可退出
            int &th=hash[t];
            if(t.size()&&!th) th=x+,Q.push(t);
        }
    }
    puts("-1");
}
int main(){
   scanf("%d",&n);
   for(int i=;i<=n;++i) cin>>s[i];
   work();
   return ;
}
 
 
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<string>
#include<map>
using namespace std;
typedef vector<int> ve;
map<ve,int>hash;
queue<ve>Q;
string s[];
int n;
void work(){
    ve u,v;
    for(int i=;i<=n;++i)
    if(s[i]=="") {puts("");exit();}
    else u.push_back(i<<);
    hash[u]=;
    Q.push(u);
    while(!Q.empty()){
        u=Q.front();
        Q.pop();
        int x=hash[u],cnt;
        for(int ch='';ch<='';++ch){
            cnt=;
            v.clear();
            for(int i=;i<(int)u.size();++i){
                int which=u[i]>>,where=u[i]&;
                if(s[which][where]^ch) continue;
                if(++where==s[which].size()) {
                    ++cnt;
                    for(int j=;j<=n;++j) v.push_back(j<<);
                }
                else v.push_back(which<<|where);
            }
            if(cnt>=) {printf("%d\n",x+);exit();}
            sort(v.begin(),v.end());   //也可以直接将v压入队列,但是要先排序
            int &th=hash[v];
            if(v.size()&&!th) th=x+,Q.push(v);
        }
    }
    puts("-1");
}
int main(){
   scanf("%d",&n);
   for(int i=;i<=n;++i) cin>>s[i];
   work();
   return ;
}
 
 

BZOJ1080 暴力+位移运算符的用法的更多相关文章

  1. JS逗号运算符的用法详解

    逗号运算符的用法详解 注意: 一.由于目前正在功读JavaScript技术,所以这里拿JavaScript为例.你可以自己在PHP中试试. 二.JavaScript语法比较复杂,因此拿JavaScri ...

  2. PHP 位移运算符(<<左移和>>右移)

    位移运算符 << 位左移 左移运算的实质是将对应的数据的二进制值逐位左移若干位,并在空出的位置上填0,最高位溢出并舍弃.例 如 $a=10; $b=$a<<2; 则$b=40, ...

  3. C#位移运算符

    代码如下: /// <summary> /// 位移运算符"<<"左位移运算符,">>"右位移运算符 /// 在进行位移运算 ...

  4. Java补码表和位移运算符

    在java中数据都是以二进制的形式保存的. 但是我们看到的数据怎么是10进制的? 因为java展示之前会自动调用toString()方法 这里以4位2进制为例,4位2进制只能表示16个数,即0-15. ...

  5. Java学习路线:Java中的位移运算符介绍

    学习java本来就是一件日积月累的事情,或许你通过自学能掌握一些皮毛技术,学到java的一些基本大面,但想要做到精通,还是需要自己技术的日积月累和工作经验的不断积累. 今天给大家分享的技术知识是:ja ...

  6. Java 中位移运算符 >>,>>>,<<

    Java 中的三种位移运算符 java中有三种移位运算符 <<      :     左移运算符,num << 1,相当于num乘以2 >>      :     ...

  7. C语言实现用位移运算符进行加减乘…

      最近,在百度知道上回答问题,然后看见有的人问如何用位移运算符去进行加减乘除运算,于是巩固今天就在这总结一下.   先讲讲总体思路: 加法运算:将一个整数用二进制表示,其加法运算就是:相异(^)时, ...

  8. 正经学C#_位移与其位移运算符[c#入门经典]

    在c#入门经典一书中,最为糟糕的一节就是位移了,完全没有讲明白,也没有说全,似乎只是轻轻点了一下何为位移,带了两次原码和补码,完全不理会是否明白不明白.这一点这本书很差.因为此书说了,在大多数应用开发 ...

  9. Lua中..和#运算符的用法

    Lua中..和#运算符的用法 样例 试试以下的样例就明确了在Lua编程语言提供的其它运算符: a = "Hello " b = "World" print(&q ...

随机推荐

  1. Linux打开文件句柄/proc/sys/fs/file-max和ulimit -n的区别

    max-file 表示系统级别的能够打开的文件句柄的数量.是对整个系统的限制,并不是针对用户的.ulimit -n 控制进程级别能够打开的文件句柄的数量.提供对shell及其启动的进程的可用文件句柄的 ...

  2. telnet 636端口不通

    今天发生了一件奇怪的事情,LDAP的636端口突然就不通了报错如下 [www@DC ~]$ telnet 10.219.90.173 636Trying10.219.90.173...Connecte ...

  3. 关于SpringBoot集成myBatis时,mapper接口注入失败的问题

    问题描述: 在Spring Boot集成myBatis时,发现启动时,mapper接口一直注入失败. 现象如下: VehicleDAO就是需要的mapper对象,一个简单的接口. 已经在applica ...

  4. 基于ONOS的T-SDN Super控制器,突破多域网络运营的难关

    在法国尼斯举办的IIR WDM波分论坛(Next Generation Optical Networking)上,华为展示了T-SDN(Transport SDN,传送SDN)领域的众多新技术,其中T ...

  5. Linux 下如何产生core文件(core dump设置)

    转自:https://blog.csdn.net/star_xiong/article/details/43529637 今天在Linux下调试C程序时,出现段错误,习惯性的ls下当前目录,发现没有生 ...

  6. Codeforces Round #622 (Div. 2) 1313 A

    Tired of boring office work, Denis decided to open a fast food restaurant. On the first day he made ...

  7. python(os 模块)

    1.os.name 输出字符串指示正在使用的平台.如果是window 则用'nt'表示,对于Linux/Unix用户,它是'posix' import os print(os.name) #结果如下 ...

  8. Alink漫谈(一) : 从KMeans算法实现不同看Alink设计思想

    Alink漫谈(一) : 从KMeans算法实现不同看Alink设计思想 目录 Alink漫谈(一) : 从KMeans算法实现不同看Alink设计思想 0x00 摘要 0x01 Flink 是什么 ...

  9. OSG程序设计之Hello World 4.0

    代码如下: //需要添加两个库:osgUtild.lib.osgTextd.lib #include <osgDB/ReadFile> #include <osgUtil/Optim ...

  10. LoadRunner安装时提示缺少C++ 2005 SP1(x86)插件

    把安装文件里的所有中文文件重命名为英 文 名就ok!!! 把安装文件里的所有中文文件重命名为英 文 名就ok!!! 把安装文件里的所有中文文件重命名为英 文 名就ok!!! 重要的事情说三遍! 不插图 ...