例题1:字串计算
样例输入
10101
样例输出
0 2
01 2
1 3
10 2
101 2
直接上代码:
#include<iostream>
#include<string>
#include<map>
using namespace std;
map<string,int>mp;//用map存储每一个子串出现的次数
string str;//字符串
int main(){
cin>>str;
int n=str.size();
for(int i=0;i<n;i++){
for(int j=1;i+j-1<n;j++){//枚举区间
mp[str.substr(i,j)]+=1;//substr用于在一个字符串中提取出某个区间
}
}
for(map<string,int>::iterator it=mp.begin();it!=mp.end();it++){//迭代器遍历map
if(it->second>1){
cout<<it->first<<" "<<it->second<<endl;//输出子串及其出现次数
}
}
return 0;
}
例题2:卡牌
样例输入
10
6
2 2 3 4 3 1
5
11 8 7 10 9
6
1000000000 1000000000 1000000000 1000000000 1000000000 1000000000
8
1 1 4 4 2 3 2 3
6
1 2 3 2 3 4
7
10 11 11 12 12 13 13
7
8 8 9 9 10 10 11
8
4 14 5 15 6 16 7 17
8
5 15 6 14 8 12 9 11
5
4 2 2 3 4
样例输出
2
1
6
2
2
2
2
2
4
3
思路:
每次找出数列中最小值,再找最小值+1是否存在,每次找最小值是ans+1,用不会去重的multiset来存储。
代码:
#include<iostream>
#include<set>
using namespace std;
int T,n,a[200010],ans;
multiset<int>st;//存储
int main(){
int t;//T组数据
cin>>T;
multiset<int>::iterator it;//先初始化一个迭代器,方便!!!
while(T--){
ans=0;//多组数据一定初始化答案
cin>>n;
for(int i=1;i<=n;i++){
cin>>t;
st.insert(t);//set常规操作
}
int tmp;
while(st.size()){
ans+=1;
tmp=*st.begin();//迭代器用法
st.erase(st.begin());//删除
while(1){//循环查找
tmp+=1;
if(st.count(tmp)){
st.erase(st.find(tmp));
}else{
break;
}
}
}
cout<<ans<<endl;
}
return 0;
}
例题3:简单的求和
样例输入
3 4
2 2 2
样例输出
3
思路:
如果直接二重循环枚举肯定会TLE,所以用map存储每个数字出现位置,只需要
时间复杂度。
代码:
#include<iostream>
#include<map>
using namespace std;
int n,k,a[100010],ans;
map<int,int>mp;
int main(){
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>a[i];
mp[a[i]]+=1;//记录每个数字出现次数
}
for(int i=1;i<=n;i++){
int t=k-a[i];//a[i]+t=k
if(t==a[i]){
ans+=mp[t]-1;
}else{
ans+=mp[t];
}
}
cout<<ans/2;//答案重复计算,除以2
return 0;
}
其实代码还有一种无需重复计算的方法,在这里就不展示了。
下一篇:贪心