代码中用到了秦九韶算法
秦九韶算法是一种多项式简化算法,它的算法复杂度是O(n)
![](https://i-blog.csdnimg.cn/blog_migrate/d2cf595b97f332b79d10e66edf61b6a0.png)
步骤如下:
![](https://i-blog.csdnimg.cn/blog_migrate/7c202f91d7a7ae17b67e576b49193f01.png)
代码如下:
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;
}
}
}
}
}