ACM-ICPC 2018 沈阳赛区网络预赛 I. Lattice‘s basics in digital electronics 哈希or字典树or暴力

86 篇文章 0 订阅

 

 

题意:

       给你n个密码,要你去破译一个被加密了的长度为m的字符。每个密码由一个字符的ASCII码和一个01字符串组成。然后给你一串加密后的字符,将字符(十六进制)先转化成二进制,然后每9个字符为一个单位(最后不满9位的也不算入答案),如果前8位字符中的‘1’的个数为奇数,第九位为‘0’或者‘1’的个数为偶数,第九位为‘1’,则这前8位为合法,可以被加入答案备选。最后处理出来的答案备选要与之前的密码对照,如上面的第二个样例 ,如果答案备选是000101101001011,且m=3, 那么前四位与49对应,5-7为与51对应,8-12位与50对应,最后的位则不要,因为答案长度为3,所以答案就是132.

       给你的密码一定合法,要你还原原字符。

 

做法:

       比赛的时候发现这道水题的时候已经没时间了,然后就写了一个纯暴力,然后T了。。。但是赛后改了一个匪夷所思的地方(把对‘a'的处理从-‘a’+10后for四次改成16个if else就过了。。喵了个咪),最后实测纯暴力是974ms。

       赛后在还没发现上面那个错误的时候又想到了字典树的做法(但是因为上面那个问题又T了。。气死了),然后就用132ms就过了。

       也参考了别的队的代码,是用哈希表做的,mp的第一维是长度,第二维是哈希出来的值,也是很神奇的处理方法,优化了不少82ms。


代码一:

  暴力

    974ms(险过。。)

 

#include<stdio.h>
#include<string>
#include<vector>
#include<map>
#include<iostream>
#include<string.h>
using namespace std;
#define pb push_back
char ans[100005],tmp[15],data[200005];
int len,anslen,lenxx;
char vis[2000005];
int xx[2000005];
map<string,int> mp;
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        len=0; anslen=0;
        lenxx=0;
        mp.clear();
        int n,m,x;
        scanf("%d%d",&m,&n);
        for(int i=1;i<=n;i++){
            int t;
            string zz;
            scanf("%d",&t);
            cin>>zz;
            mp[zz]=t;
        }
        scanf("%s",data);
        for(int i=0;i<strlen(data);i++){
            if(data[i]=='0'){
                xx[++lenxx]=0;xx[++lenxx]=0;xx[++lenxx]=0;xx[++lenxx]=0;
            }
            else if(data[i]=='1'){
                xx[++lenxx]=0;xx[++lenxx]=0; xx[++lenxx]=0;xx[++lenxx]=1;
            }
            else if(data[i]=='2'){
                xx[++lenxx]=0;xx[++lenxx]=0;xx[++lenxx]=1;xx[++lenxx]=0;
            }
            else if(data[i]=='3'){
                xx[++lenxx]=0;xx[++lenxx]=0;xx[++lenxx]=1;xx[++lenxx]=1;
            }
            else if(data[i]=='4'){
                xx[++lenxx]=0;xx[++lenxx]=1;xx[++lenxx]=0;xx[++lenxx]=0;
            }
            else if(data[i]=='5'){
                xx[++lenxx]=0;xx[++lenxx]=1;xx[++lenxx]=0;xx[++lenxx]=1;
            }
            else if(data[i]=='6'){
                xx[++lenxx]=0;xx[++lenxx]=1;xx[++lenxx]=1;xx[++lenxx]=0;
            }
            else if(data[i]=='7'){
                xx[++lenxx]=0;xx[++lenxx]=1;xx[++lenxx]=1;xx[++lenxx]=1;
            }
            else if(data[i]=='8'){
                xx[++lenxx]=1;xx[++lenxx]=0;xx[++lenxx]=0;xx[++lenxx]=0;
            }
            else if(data[i]=='9'){
                xx[++lenxx]=1;xx[++lenxx]=0;xx[++lenxx]=0;xx[++lenxx]=1;
            }
            else if(data[i]=='a'||data[i]=='A'){
                xx[++lenxx]=1;xx[++lenxx]=0;xx[++lenxx]=1;xx[++lenxx]=0;
            }
            else if(data[i]=='b'||data[i]=='B'){
                xx[++lenxx]=1;xx[++lenxx]=0;xx[++lenxx]=1;xx[++lenxx]=1;
            }
            else if(data[i]=='c'||data[i]=='C'){
                xx[++lenxx]=1;xx[++lenxx]=1;xx[++lenxx]=0;xx[++lenxx]=0;
            }
            else if(data[i]=='d'||data[i]=='D'){
                xx[++lenxx]=1;xx[++lenxx]=1;xx[++lenxx]=0;xx[++lenxx]=1;
            }
            else if(data[i]=='e'||data[i]=='E'){
                xx[++lenxx]=1;xx[++lenxx]=1;xx[++lenxx]=1;xx[++lenxx]=0;
            }
            else if(data[i]=='f'||data[i]=='F'){
                xx[++lenxx]=1;xx[++lenxx]=1;xx[++lenxx]=1;xx[++lenxx]=1;
            }
        }
        for(int i=1;i<=lenxx;i+=9){
            if(i+9>lenxx+1) break;
            int zz=0;
            for(int j=i;j<8+i;j++){
                if(xx[j]==1) zz++;
            }
            if(zz%2&&xx[i+8]==0||zz%2==0&&xx[i+8]==1){
                for(int z=i;z<i+8;z++){
                    vis[++len]=xx[z]+'0';
                }
            }
        }
        //printf("%s\n",vis+1);
        string tmp="";
        for(int i=1;i<=len;i++){
            tmp=tmp+vis[i];
            if(mp[tmp]){
                ans[anslen++]=(char)mp[tmp];
                tmp="";
                if(anslen==m) break;
            }
        }
        ans[anslen]='\0';
        printf("%s\n",ans);
    }
	return 0;
}

 

代码二:

   字典树

103ms

#include<stdio.h>
#include<string>
#include<iostream>
#include<string.h>
#include<map>
using namespace std;
#define pb push_back
char tmp[15],data[200005];
int len,anslen,lenxx;
char vis[1000005];
char xx[1000005];
int trie[1000005][2],sum[1000005],tot;
void Insert(char *s,int as){
    int len=strlen(s),rt=0;
    for(int i=0;i<len;i++){
        int aim=s[i]-'0';
        if(!trie[rt][aim]) trie[rt][aim]=++tot;
        if(i==len-1) sum[trie[rt][aim]]=as;
        rt=trie[rt][aim];
    }
}
int Search(char *s,int now,int &nex,int len){
    int rt=0;
    for(int i=now;i<len;i++){
        int aim=s[i]-'0';
        if(sum[trie[rt][aim]]){
            nex=i;
            return sum[trie[rt][aim]];
        }
        rt=trie[rt][aim];
    }
    return -1;
}
int main(){
    int t;
    char tmps[15];
    scanf("%d",&t);
    while(t--){
        memset(trie,0,sizeof(trie));
        memset(sum,0,sizeof(sum));
        tot=0;
        len=0; anslen=0;
        lenxx=0;
        int n,m,x;
        scanf("%d%d",&m,&n);
        for(int i=1;i<=n;i++){
            int tt;
            scanf("%d%s",&tt,tmps);
            Insert(tmps,tt);
        }
        scanf("%s",data);
        for(int i=0;i<strlen(data);i++){
            if(data[i]=='0'){
                xx[++lenxx]=0;xx[++lenxx]=0;xx[++lenxx]=0;xx[++lenxx]=0;
            }
            else if(data[i]=='1'){
                xx[++lenxx]=0; xx[++lenxx]=0;xx[++lenxx]=0;xx[++lenxx]=1;
            }
            else if(data[i]=='2'){
                xx[++lenxx]=0;xx[++lenxx]=0;xx[++lenxx]=1;xx[++lenxx]=0;
            }
            else if(data[i]=='3'){
                xx[++lenxx]=0;xx[++lenxx]=0;xx[++lenxx]=1;xx[++lenxx]=1;
            }
            else if(data[i]=='4'){
                xx[++lenxx]=0;xx[++lenxx]=1;xx[++lenxx]=0;xx[++lenxx]=0;
            }
            else if(data[i]=='5'){
                xx[++lenxx]=0;xx[++lenxx]=1;xx[++lenxx]=0;xx[++lenxx]=1;
            }
            else if(data[i]=='6'){
                xx[++lenxx]=0;xx[++lenxx]=1;xx[++lenxx]=1;xx[++lenxx]=0;
            }
            else if(data[i]=='7'){
                xx[++lenxx]=0;xx[++lenxx]=1;xx[++lenxx]=1;xx[++lenxx]=1;
            }
            else if(data[i]=='8'){
                xx[++lenxx]=1;xx[++lenxx]=0;xx[++lenxx]=0;xx[++lenxx]=0;
            }
            else if(data[i]=='9'){
                xx[++lenxx]=1;xx[++lenxx]=0;xx[++lenxx]=0;xx[++lenxx]=1;
            }
            else if(data[i]=='a'||data[i]=='A'){
                xx[++lenxx]=1;xx[++lenxx]=0;xx[++lenxx]=1;xx[++lenxx]=0;
            }
            else if(data[i]=='b'||data[i]=='B'){
                xx[++lenxx]=1;xx[++lenxx]=0;xx[++lenxx]=1;xx[++lenxx]=1;
            }
            else if(data[i]=='c'||data[i]=='C'){
                xx[++lenxx]=1;xx[++lenxx]=1;xx[++lenxx]=0;xx[++lenxx]=0;
            }
            else if(data[i]=='d'||data[i]=='D'){
                xx[++lenxx]=1;xx[++lenxx]=1;xx[++lenxx]=0;xx[++lenxx]=1;
            }
            else if(data[i]=='e'||data[i]=='E'){
                xx[++lenxx]=1;xx[++lenxx]=1;xx[++lenxx]=1;xx[++lenxx]=0;
            }
            else if(data[i]=='f'||data[i]=='F'){
                xx[++lenxx]=1;xx[++lenxx]=1;xx[++lenxx]=1;xx[++lenxx]=1;
            }
        }

        for(int i=1;i<=lenxx;i+=9){
            int zz=0;
            for(int j=i;j<8+i;j++){
                    if(xx[j]==1) zz++;
            }
            if(zz%2&&xx[8+i]==0||zz%2==0&&xx[8+i]==1){
                    for(int j=i;j<i+8;j++){
                        vis[++len]=xx[j]+'0';
                    }
            }
        }
        //printf("%s\n",vis+1);
        int no=1,ne,cas=0;
        while(1){
            int az=Search(vis,no,ne,len+1);
            printf("%c",az);
            if(++cas==m) break;
            no=ne+1;
        }
        printf("\n");
    }
	return 0;
}

 

代码三:

    哈希

81ms

#include<stdio.h>
#include<string.h>
using namespace std;
#define pb push_back
char ans[100005],tmp[15],data[200005];
int lenxx,anslen,len;
int vis[1000005],xx[1000005],mp[15][2005];
int a[12]={1,2,4,8,16,32,64,128,256,512,1024,2048};
int main(){
    int t;
    char tmps[15];
    scanf("%d",&t);
    while(t--){
        memset(mp,0,sizeof(mp));
        len=lenxx=0;
        int n,m,x;
        scanf("%d%d",&m,&n);
        for(int i=1;i<=n;i++){
            int tt,nn=0,l;
            scanf("%d%s",&tt,tmps);
            l=strlen(tmps);
            for(int j=0;j<l;j++){
                int wh=tmps[j]-'0';
                nn=nn+a[j]*wh;
            }
            mp[l][nn]=tt;
        }
        scanf("%s",data);
        
        for(int i=0;i<strlen(data);i++)
        {
            if(data[i]=='0'){
                xx[++lenxx]=0;xx[++lenxx]=0;xx[++lenxx]=0;xx[++lenxx]=0;
            }
            else if(data[i]=='1'){
                xx[++lenxx]=0;xx[++lenxx]=0;xx[++lenxx]=0;xx[++lenxx]=1;
            }
            else if(data[i]=='2'){
                xx[++lenxx]=0;xx[++lenxx]=0;xx[++lenxx]=1;xx[++lenxx]=0;
            }
            else if(data[i]=='3'){
                xx[++lenxx]=0;xx[++lenxx]=0;xx[++lenxx]=1;xx[++lenxx]=1;
            }
            else if(data[i]=='4'){
                xx[++lenxx]=0;xx[++lenxx]=1;xx[++lenxx]=0;xx[++lenxx]=0;
            }
            else if(data[i]=='5'){
                xx[++lenxx]=0;xx[++lenxx]=1;xx[++lenxx]=0;xx[++lenxx]=1;
            }
            else if(data[i]=='6'){
                xx[++lenxx]=0;xx[++lenxx]=1;xx[++lenxx]=1;xx[++lenxx]=0;
            }
            else if(data[i]=='7'){
                xx[++lenxx]=0;xx[++lenxx]=1;xx[++lenxx]=1;xx[++lenxx]=1;
            }
            else if(data[i]=='8'){
                xx[++lenxx]=1;xx[++lenxx]=0;xx[++lenxx]=0;xx[++lenxx]=0;
            }
            else if(data[i]=='9'){
                xx[++lenxx]=1;xx[++lenxx]=0;xx[++lenxx]=0;xx[++lenxx]=1;
            }
            else if(data[i]=='a'||data[i]=='A'){
                xx[++lenxx]=1;xx[++lenxx]=0;xx[++lenxx]=1;xx[++lenxx]=0;
            }
            else if(data[i]=='b'||data[i]=='B'){
                xx[++lenxx]=1;xx[++lenxx]=0;xx[++lenxx]=1;xx[++lenxx]=1;
            }
            else if(data[i]=='c'||data[i]=='C'){
                xx[++lenxx]=1;xx[++lenxx]=1;xx[++lenxx]=0;xx[++lenxx]=0;
            }
            else if(data[i]=='d'||data[i]=='D'){
                xx[++lenxx]=1;xx[++lenxx]=1;xx[++lenxx]=0;xx[++lenxx]=1;
            }
            else if(data[i]=='e'||data[i]=='E'){
                xx[++lenxx]=1;xx[++lenxx]=1;xx[++lenxx]=1;xx[++lenxx]=0;
            }
            else if(data[i]=='f'||data[i]=='F'){
                xx[++lenxx]=1;xx[++lenxx]=1;xx[++lenxx]=1;xx[++lenxx]=1;
            }
        }
        for(int i=1;i<=lenxx;i+=9){
            if(i+9>lenxx+1) break;
            int zz=0;
            for(int j=i;j<8+i;j++){
                if(xx[j]==1) zz++;
            }
            if(zz%2&&xx[i+8]==0||zz%2==0&&xx[i+8]==1){
                for(int z=i;z<i+8;z++){
                    vis[++len]=xx[z];
                }
            }
        }

        int lens=0,b=0,cas=0;
        for(int i=1;i<=len;i++){
            b+=vis[i]*a[lens++];
            if(mp[lens][b]){
                printf("%c",mp[lens][b]);
                if(++cas==m) break;
                lens=0,b=0;
            }
        }
        printf("\n");
    }
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值