map pair string

一、pair
1.定义:“二元结构题的替代品”;实际就是含有两个变量的结构体;
相当于:struct pair{
typename1 first;
typename2 second;
}
pair有两个参数,分别对应first和second的数据类型,可以是任意基本数据类型或者容器。
2.定义一个pair的方法为:
pair<typename1,typename2> name;
/* 在pair内会自动排序:先按 typename1从小到大排 :typename1相同;
按typename2从小到大排序*/
3.头文件.#include ,同时,必须要有“using namespace std” ,包含于#include<bits/stdc++.h>中。

二、string
1.C++在STL中加入了string类型,比char str []更方便存储,不必担心内存是否足够、字符串的长度等问题。
2. 定义string的方法为:string name;;
string name [10] 是指有10个名字需要存储;
3.头文件:#include ,同时必须要有“using namespace std”,包含于#include<bits/stdc++.h>中。
4.string的访问:
string str= “ abcd “ ;
for(int i = 0; i < str.length(); i++) printf( “ %c “ ,str[i]);
5.如果要读入或者输出整个字符串,一般只能用cin和cout。如果非要用printf输出string,则需要用c_str()函数将string转换成字符数组。例如:
string str;
cin>>str;
cout<<str<<endl;
printf("%s\n",str.c_str());

三、map
1.定义: map翻译为映射,是STL中的常用容器。(可存储数据)
2.头文件:#include ,同时必须要有“using namespace std”,包含于#include<bits/stdc++.h>中。
(因为map的内部实现中涉及pair,因此添加map头文件时会自动添加utility头文件,此时可以省去utility头文件。)
3.map与数组区别:
数组总是将int类型映射到其它基本类型(称为数组的基类型)。
map:map可以将任何基本类型(包括STL容器)映射到任何基本类型(包括STL容器)。
4.map的定义使用:
定义一个map的方法为:map<typename1,typename2> name;
typename1是映射前的类型(键key),typename2是映射后的类型(值value),name为映射的名字。
map的嵌套: map<map<int,int>int>vis;
map<pair<int,int>,int>;
5.map 的访问:
map<int,int>vis;
(1)下标访问:
vis[x];
(2)迭代器访问:(访问全部元素)
正向遍历 :
map<int,int>::iterator it;
for(it=vis.begin();it!=vis.end();;it++)
printf("%d%d,it->first,it->second);
反向遍历:
map<int,int>::reverse it;
for(it=vis.rbegin();it!=vis.rend();;it++)
printf("%d%d,it->first,it->second);
6.map的函数:
(1)find():用find函数来定位数据出现位置,它返回的一个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器。
(2)size():用来获得map中映射的对数;
(3)clear()用来清空map();
(4)erase()删除元素:
erase(it)删除单个元素;
erase(first,second)删除区间内元素;
题目
problem A:查字典
nefu 1678

#include <bits/stdc++.h>
using namespace std;
 map<string,int>vis;/*定义变量名*/
int main()
{
  ios::sync_with_stdio();
  int n,m,page;
  string word1,word2;
  cin>>n;
  for(int i=0;i<n;i++)
 {
    cin>>word1>>page;/*输入word1的同时相当于将输入了map中*/
    vis[word1]=page;/*再将page输入到map中*/
 }
    cin>>m;
   while(m--)
  {
      cin>>word2;
  printf("%d\n",vis[word2]);
  }
 return 0;
}

problem B:保龄球-map
nefu 1687

#include <bits/stdc++.h>
using namespace std;
 map<long long ,int>vis;
int main()
{
  int n,m;
long long x;
scanf("%d",&n);
  for(int i=1;i<=n;i++)
 {
   scanf("%lld",&x);
    vis[x]=i;
 }
scanf("%d",&m);
   while(m--)
  {
   scanf("%lld",&x);
  printf("%d\n",vis[x]);/*如果map中没有xvis[x]为0*/
  }
 return 0;
}

problem C:眼红的Medusa
nefu 1686

#include <bits/stdc++.h>
using namespace std;
 map<long long ,int>vis;
int main()
{
  int n,m;
long long a[100001];
long long x;
scanf("%d%d",&n,&m);
  for(int i=0;i<n;i++)
 {
   scanf("%lld",&a[i]);
    vis[a[i]]=1;/*把第一组数据作为参照,后面还会用到,所以要做一下标记*/
 }
  for(int i=0;i<m;i++)
  {
   scanf("%lld",&x);
     vis[x]++;
  }
  for(int i=0;i<n;i++)
    if(vis[a[i]]==2)printf("%lld ",a[i]);
 return 0;
}

problem E:指数序列
nefu 1677
抓住两点:
1.有数学公式可知 2^v-1= 20+21+22+……2(v-1);
也就是说2^v-1的二进制每一位都为1;
所以找出二进制位为0的个数在补上就可以了;
即找出从0到v-1中间缺的数字;
2.由于2x+2x=2^(x+1),对于一个非降序列,我们可以向上进位得到单调递增序列,如:
1 1 2 3 5——>2 2 3 5——>3 3 5——>4 5

方法一:暴力的方法:

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const  int N=1e5+10;
const long long int M=1e18;
ll a[N];
map<ll,int>vis;
int main()
{
    int n;
     cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    ll ans=a[1];/*a[1]的大小就是第一个元素前面要补的数*/
    a[n+1]=M;/*写a[n+1]是为了循环能判断a[n]*/
    for(int i=1;i<=n+1;i++)
    {
        if(a[i]!=a[i-1]&&(i!=1))
        {
            for(int j=a[i-1];j<a[i];j++)
            {
                if(!vis[j])/*当vis[j]为0时,一般是a[i-1]++的元素*/
                {
                    if(i!=n+1)ans+=a[i]-j;/*加上中间空余的元素个数*/
                    break;
                }
                while(vis[j]>=2)/*所说的点2的进位*/
                {
                    vis[j]-=2;
                    vis[j+1]++;
                }
                if(!vis[j])ans++;/*空缺的元素补上,要做一下标记*/
            }
        }
        vis[a[i]]++;/*当i=1时只进行这一步vis[a[1]]++,当出现相等的元素一直++*/
    }
    cout<<ans<<endl;
    return 0;
}

方法二:用map

#include <bits/stdc++.h>
using namespace std;
int main()
{
	int n;
    long long num=0,x,cnt;
    map<long long,int>vis;
    scanf("%lld",&n);
    while(n--)
    {
    	scanf("%lld",&x);
    	vis[x]++; /*标记x出现过*/
    	if(vis[x]==2)
    	{
    		for(long long i=x;vis[i]==2;i++) /*进位*/
    		{
    			vis[i]-=2;
    			vis[i+1]++;
			}
		}
	}
	map<long long,int>::iterator it;
    for(it=vis.begin();it!=vis.end();it++)
	{
		if(it->second!=0) /*判断一下是否被减到0*/
		{
			cnt++; /*计算1的个数*/
			if(it->first>num)num=it->first; /*找到最大位数*/
		}
	}
	printf("%lld",num<cnt?0:num-cnt+1);/*若num小于cnt(1的个数)输出num-cnt+1,加一是因为0也要有*/
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值