ACM-ICPC 2018 沈阳赛区网络预赛 I. Lattice's basics in digital electronics 字典树 + 模拟

1.题意:(题意巨巨巨巨巨长)

给出一串16进制的字符串,把他转化为二进制。然后给你一些二进制串 si 对应的字符ACII码 ci (每个si串前缀不同),然后给你对于转化为二进制后的字符串的算法规则:

八个字符为一个部分,第九个字符时有两种情况:

(1)若前八个字符内含有奇数个1且第九个字符为0  或者  前八个字符内含有偶数个1且第九个字符为1 则保留前八位

(2)否则这九位全部舍弃

然后对于处理好的最终字符串,把他按照si跟ci的对应规则转化为相应字符输出,注意:这里限定输出n个字符,多于不输出(坑点)

2.分析:

预处理16进制到二进制,处理保留字符串,把对应规则保存到字典树。输出最终字符串时跑一下字典数即可。

3.代码:

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
const int maxn = 200000 + 1;
char chara[] = "0123456789ABCDEF";//编号对应16进制单位
char hexd[][10] = {"0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111"};//预处理每个16进制对应四位二进制
int rela[100];
struct Node{
   int next[2];
   bool judge;
   int sign;
}node[maxn*4];
char ans[4*maxn];
char sum[4*maxn];
char compare[maxn];
int n,m,tot,mm;
void init(){
  for(int i = 0;i<16;i++){//初始化16进制每个单位对应编号
      int j = chara[i] - '0';
      rela[j] = i;
  }
}
int CreatTree(){//添加节点
   node[tot].next[0] = node[tot].next[1] = -1;
   node[tot].judge = false;
   node[tot].sign = 0;
   return tot++;
}
void InsertTree(int a,char*s){//插入
   int index = 0;
   int l = strlen(s);//这里一定先求出strlen,不要用for(int i = 0;i<strlen(s);i++)超时。。
   for(int i = 0;i<l;i++){
       int j = s[i] - '0';
       if(node[index].next[j]==-1){
           node[index].next[j] = CreatTree();
       }
       index = node[index].next[j];
   }
   node[index].judge = true;
   node[index].sign = a;
}
void FindTree(char *s,int len){//查找
    int index = 0;
    for(int i = 0;i<len;i++){
        int j = s[i] - '0';
        index = node[index].next[j];
        if(node[index].judge){
            printf("%c",node[index].sign);//输出
            mm++;
            if(mm==n)break;//达到限制跳出
            index = 0;
        }
    }
    printf("\n");
}
int main()
{
    int T;
    init();
    scanf("%d",&T);
    while(T--){
        mm = 0;
        tot = 0;
        CreatTree();
        scanf("%d%d",&n,&m);
        for(int i = 0;i<m;i++){
            char str[20];
            int name;
            scanf("%d%s",&name,str);
            InsertTree(name,str);//对应规则保存到字典树
        }
        scanf("%s",compare);
        int l = 0;
        int ll = strlen(compare);
        for(int i = 0;i<ll;i++){
            if(compare[i]>='a'&&compare[i]<='f')compare[i]-=32;//小写转换大写
            for(int j = 0;j<4;j++){
                ans[l++] = hexd[rela[compare[i] - '0']][j];//16进制转换为对应2二进制保存
            }
        }
        ans[l] = '\0';
        int p = 0;
        int num = 0;
        for(int i = 0;i<l;i++){//处理串
            if((i+1)%9==0){
                if(((p%2==1)&&ans[i]=='0')||((p%2==0)&&ans[i]=='1')){//决定是否保存
                    for(int j = i-8;j<i;j++){
                        sum[num++] = ans[j];
                    }
                }
                p = 0;
            }
            else if(ans[i]=='1')p++;
        }
        sum[num] = '\0';//sum是最终串
        FindTree(sum,num);//输出
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/qq_40772692/article/details/82561443