蓝桥杯集训·每日一题 AcWing 2058笨拙的手指(哈希表)

题目链接:2058.笨拙的手指

代码中用到了秦九韶算法

秦九韶算法是一种多项式简化算法,它的算法复杂度是O(n)

步骤如下:

代码如下:

unordered_set写法

#include<bits/stdc++.h>
using namespace std;
string ss,sss;
int base(string s,int n){//秦九韶算法 
    int res=0;
    for(auto i:s){
        res=res*n+i-'0';
    }
    return res;
}
int main(){
    cin>>ss>>sss;
    unordered_set<int>hash;//unordered_set哈希表来表示某个数字是否出现过
    for(int i=0;i<ss.size();i++){
        string s=ss;
        s[i]^=1;//0->1,1->0,巧妙技巧
        if(s.size()>1&&s[0]=='0') continue;//排除原数存在前导0的情况 
        int n=base(s,2);
        hash.insert(n);
    }
    for(int i=0;i<sss.size();i++){
        for(int j=0;j<3;j++){
            if(sss[i]!=j+'0'){//注意要写 j+'0',如果写成j-'0'没有输出 
                string s=sss;//注意 
                s[i]=j+'0';
                if(s.size()>1&&s[0]=='0') continue;
                int n=base(s,3);
                if(hash.count(n)){//count返回集合内某个数字出现的次数
                    cout<<n;
                }
            }
        }    
    }
}

手写哈希表写法

#include<bits/stdc++.h>
using namespace std;
string ss,sss;
const int N=103;//此题中对应的二进制数最多30,哈希表的规格开2~3倍 
int h[N]; 
int find(int x){
    int t=x%N;//t为在哈希表中的位置下标 
    while(h[t]!=-1&&h[t]!=x){//代表此位置已经有数,h[t]!=x表示且这个数不是x本身 
        t++;//则换相邻的位置 
        if(t==N) t=0;//如果 已经到最后一个位置,则从头开始 
    }
    return t; 
} 
int base(string s,int n){//秦九韶算法 
    int res=0;
    for(auto i:s){
        res=res*n+i-'0';
    }
    return res;
}
int main(){
    cin>>ss>>sss;
    memset(h,-1,sizeof(h));
    for(int i=0;i<ss.size();i++){
        string s=ss;
        s[i]^=1;//0->1,1->0
        if(s.size()>1&&s[0]=='0') continue;//排除原数存在前导0的情况 
        int n=base(s,2);
        h[find(n)]=n;//找到n所在的位置并且填上 
    }
    for(int i=0;i<sss.size();i++){
        for(int j=0;j<3;j++){
            if(sss[i]!=j+'0'){//注意要写 j+'0',如果写成j-'0'没有输出 
                string s=sss;//注意 
                s[i]=j+'0';
                if(s.size()>1&&s[0]=='0') continue;
                int n=base(s,3);
                if(h[find(n)]!=-1){//count返回集合内某个数字出现的次数
                    cout<<n;
                }
            }
        }    
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值