例题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;
} 
其实代码还有一种无需重复计算的方法,在这里就不展示了。
下一篇:贪心



















