题意:
给你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;
}