首行输入两个整数N,M(1<=N<=15000,1<=M<=100000),之后是N行输入,表示有N个手机号码,每个手机号码由11位首位不为零的连续数字组成,接着是M行查询,每行由连续的数字组成,长度为L(1<=L<=11)。
每个请求输出包含查询数字串的不同的手机号共有多少个。
3 2 15623651459 18956036508 18625690367 333 036
0 2
输入手机号可能有冗余
#include<bits/stdc++.h> using namespace std; const int maxn = 1e3+5; typedef long long ll; unordered_map<string,bool>vis; unordered_map<string,int>cnt; int main(){ ios::sync_with_stdio(false); cin.tie(0); int n,m; cin>>n>>m; string s; while(n--){ cin>>s; if(vis.count(s)) continue; vis[s]=true; set<string>st; for(int i=0;i<11;i++){ for(int j=i;j<11;j++){ st.insert(s.substr(i,j-i+1)); } } for(auto t:st) cnt[t]++; } while(m--){ cin>>s; cout<<cnt[s]<<'\n'; } return 0; }
//map去重+双hash+散列表,内存差点炸了,精打细算一下刚刚好 /*author: revolIA*/ #include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<unsigned int,unsigned int> pll; inline pll operator - (pll a,pll b){return make_pair((a.first - b.first),(a.second - b.second));} inline pll operator * (pll a,pll b){return make_pair((a.first * b.first),(a.second * b.second));} inline pll operator + (pll a,pll b){return make_pair((a.first + b.first),(a.second + b.second));} inline pll operator + (pll a,int b){return make_pair((a.first + b ),(a.second + b ));} const int maxn = 1e6+7; const pll p = {23,2333}; int n,m; char opt[20]; int head[maxn],Next[maxn],cnt; pair<pll,int> val[maxn]; int Find(pll x){ int pos = (int)(x.first*x.second%maxn); for(int i=head[pos];i;i=Next[i])if(x == val[i].first) return i; return -1; } void Insert(pll x){ int pos = Find(x); if(~pos){ val[pos].second++; return; } pos = (int)(x.first*x.second%maxn); val[++cnt] = {x,1}; Next[cnt] = head[pos]; head[pos] = cnt; } map<pll,bool> vis,tvis; int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%s",opt+1); pll ans = {0,0}; for(int i=1;i<=11;i++)ans = ans*p+opt[i]; if(tvis.count(ans)) continue; tvis[ans] = 1; vis.clear(); for(int l=1;l<=11;l++){ ans = {0,0}; for(int r=l;r<=11;r++){ ans = ans*p+opt[r]; if(!vis.count(ans)){ ++vis[ans]; Insert(ans); } } } } for(int i=1;i<=m;i++){ scanf("%s",opt+1); pll tmp = {0,0}; for(int j=1;opt[j];j++){ tmp = tmp*p+opt[j]; } int pos = Find(tmp); printf("%d\n",pos!=-1?val[pos].second:0); } return 0; }
#include<bits/stdc++.h> using namespace std; int main(){ int i,j,n,q; unordered_map<string,int>m; scanf("%d%d",&n,&q); while(n--){ string s; cin>>s; unordered_set<string>c; for(i=0;i<11;++i){ string t; for(j=i;j<11;++j){ t+=s[j]; c.insert(t); } } for(auto p:c)m[p]++; } while(q--){ string s; cin>>s; cout<<m[s]<<endl; } return 0; }
#include <bits/stdc++.h> using namespace std; int n, m; unordered_set<string> objs; unordered_map<string, int> cnt; int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n >> m; for (int i = 0; i < n; i ++) { string s; cin >> s; objs.emplace(s); } for (auto &i : objs) { if (i.size() != 11) continue; unordered_map<string, bool> st; for (int idx = 0; idx < 11; idx ++) { for (int k = 1; k <= 11 - idx; k ++) { string tmp = i.substr(idx, k); if (st[tmp]) continue; st[tmp] = 1; cnt[tmp] ++; } } } for (int i = 0; i < m; i ++) { int res = 0; string s; cin >> s; cout << cnt[s] << "\n"; } }
import java.util.*; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int N = scanner.nextInt(), M = scanner.nextInt(); // String[] checks = new String[N]; Map<String, Integer> hashMap = new HashMap<>(); Set<String> strings = new HashSet<>(); scanner.nextLine(); for (int i = 0; i < N; i++) { String s = scanner.nextLine(); if (s.length() == 11 && strings.add(s)) { Set<String> checks = new HashSet<>(); for (int j = 0; j < 11; j++) { for (int k = j + 1; k <= 11; k++) { String s1=s.substring(j, k); if (checks.add(s1)){ hashMap.put(s1, hashMap.getOrDefault(s1, 0) + 1); } } } } } for (int i = 0; i < M; i++) { String query = scanner.nextLine(); System.out.println(hashMap.getOrDefault(query, 0)); } } }
#include <iostream> #include <string> using namespace std; bool func(string number, string phoneNumber){ for(int i = 0; i < phoneNumber.length();i++){ if(number[0]==phoneNumber[i] && (i+number.length())<phoneNumber.length()){ int j; for(j = 1; j <number.length();j++){ if(number[j]!=phoneNumber[i+j]){ break; } } if(j==number.length()){return true;} } } return false; }; int main() { string phoneNumber[15000]={},number[10000]={}; int N, M; cin >> N >> M; //输入 for(int i = 0; i<N; i++){ cin >> phoneNumber[i]; } for(int i = 0;i<M;i++){ cin >> number[i]; } //统计 for(int i = 0; i<M; i++){ int cnt = 0; for(int j = 0;j<N;j++){ if(func(number[i],phoneNumber[j])){ cnt++; } } cout << cnt <<endl; } return 0;我在自己的环境上测试本样例通过了,有无大佬看看我哪出问题了(用的最简单粗暴的逐项对比法)
#include <iostream> #include <string> #include <array> #include <vector> using namespace std; void function() { int n_str, n_num; cin >> n_num>>n_str; // n_num个号码 n_str个子串 vector<int> count(n_str,0); array<string, 10> arr_str, arr_num; // 子串 号码 string s; for (int i = 0; i < n_num; i++) { cin >> s; arr_num[i] = s; } for (int i = 0; i < n_str; i++) { cin >> s; arr_str[i] = s; } for (int i = 0; i < n_str; i++) { for (int j = 0; j < arr_num.size(); j++) { if (arr_num[j].find(arr_str[i]) != std::string::npos) count[i]++; } } for (int val : count) cout << val << endl; } int main() { function(); return 0; }
#include<bits/stdc++.h> using namespace std; int main(){ int i,j,n,q; unordered_map<string,int>m;//用于记录连续数字出现的数字,key=连续数字,value=次数 cin>>n>>q;//n个手机号码,q个查询数字段 unordered_set<string>phone;//用set进行存储避免了号码的重复插入 string s; while(n--){ cin>>s; if(s.size()!=11)continue;//不是正确的电话号码则不必存储 phone.insert(s);//用set进行插入,避免号码的重复 } for(unordered_set<string>::iterator it=phone.begin();it!=phone.end();++it){ s=*it; unordered_set<string>c; for(i=0;i<11;++i){ string t; for(j=i;j<11;++j){ t+=s[j]; c.insert(t);//将一个手机号码所有的连续组合方式进行存储,用空间替换时间 } } for(auto p:c)m[p]++;//计数 } while(q--){ cin>>s;//输入连续数字段 cout<<m[s]<<endl;//输出他的次数 } return 0; }注:直接用数学的查找方式if (phonenum[i].find(test) != string::npos)会超时,只能AC80%,这里用空间替换时间效率AC了100%。截取一个号码所有可能的连续组合方式,从而节约了find的时间。
#include<iostream> #include<string> using namespace std; int main() { int N,M; cin >> N >> M; string pnum[N]; string fnum[M]; int i=0; int j=0; int count = 0; int a; while(N--) //N = 3 { cin >> pnum[i]; i++; } while(M--)//M = 2 { cin >> fnum[j]; j++; } for(int p=0;p<M;p++) { for(int q=0;q<N;q++) { a = pnum[q].find(fnum[p]); if(a != -1) { count++; } } cout << count << endl; } return 0; }
#include<iostream> (720)#include<string> #include<vector> using namespace std; int main() { unsigned int M, N; cin >> N; cin >> M; vector<string>Num; for (int i = 0; i < N; i++) { string temp; cin >> temp; Num.push_back(temp); } vector<string>Chack; for (int i = 0; i < M; i++) { string temp; cin >> temp; Chack.push_back(temp); } for (vector<string>::iterator it1=Chack.begin();it1!=Chack.end();it1++) { int out = 0; for (vector<string>::iterator it2 = Num.begin(); it2 != Num.end(); it2++) { int pos = (*it2).find((*it1)); if (pos != -1) { out++; } } cout << out << endl; } return 0; }
private static void solution(String[] pNumbers,String[] tNumbers,int phoneNumbers,int targetNumbers) { int num =0; for (int i = 0; i < targetNumbers; i++) { for (int j = 0; j < phoneNumbers; j++) { if(pNumbers[j].contains(tNumbers[i])) num++; } System.out.println(num); num=0; } }这样写有个双重循环超时了,请问有别的方法解决问题吗?
参考一下90%的代码吧(仅供参考
#include <bits/stdc++.h> using namespace std; unordered_map<string, int>buffmap; int main() { std::ios::sync_with_stdio(false); int N, count;cin >> N >> count; vector<string>buff(N, ""); for (int i = 0; i < N; ++ i) { cin >> buff[i]; } for (int i = 0; i < N; ++i) { unordered_set<string> buffset; for (int j = 0; j < buff[i].length(); ++j) for (int k = j; k < buff[i].length(); ++k) buffset.insert(buff[i].substr(j, k - j + 1)); for (auto iter = buffset.begin(); iter != buffset.end(); ++iter) { buffmap[*iter] ++; } } while (count --) { string str; cin >> str; cout << buffmap[str] << endl; } return 0; }