c++编程题 彩色宝石项链

题目描述

有一条彩色宝石项链,是由很多种不同的宝石组成的,包括红宝石,蓝宝石,钻石,翡翠,珍珠等。有一天国王把项链赏赐给了一个学者,并跟他说,你可以带走这条项链,但是王后很喜欢红宝石,蓝宝石,紫水晶,翡翠和钻石这五种,我要你从项链中截取连续的一小段还给我,这一段中必须包含所有的这五种宝石,剩下的部分你可以带走。如果无法找到则一个也无法带走。请帮助学者找出如何切分项链才能够拿到最多的宝石。

输入描述:

我们用每种字符代表一种宝石,A表示红宝石,B表示蓝宝石,C代表紫水晶,D代表翡翠,E代表钻石,F代表玉石,G代表玻璃等等,我们用一个全部为大写字母的字符序列表示项链的宝石序列,注意项链是首尾相接的。每行代表一种情况。

输出描述:

输出学者能够拿到的最多的宝石数量。每行一个

示例1

输入

ABCYDYE
ATTMBQECPD

输出

1
3
//尺取法,求包含ABCDE的最短字串
#include<iostream>
#include<string>
#include<algorithm>
#include<map>
using namespace std;
int main(){
    string s;
    int i,j,num,len;
    while(cin>>s){
        len=s.length();
        s=s+s;
        i=0,j=0,num=0;
        int Min=len;
        //用map一对一映射反应是否已经包含ABCDE五个字符
        map<char,int> book;
        while(true){
            while(i<s.length()&&num<5){
            //遍历到A,则book['A']自增为1,下次再遍历A则不满足if
            //num代表已经遍历到的ABCDE中几个字符  
                  if((s[i]=='A'||s[i]=='B'||s[i]=='C'||s[i]=='D'||s[i]=='E')
                    &&book[s[i]]++==0)
                    num++;
                i++; //右指针向右移动
            }
            //当右指针到达字符串右边界时,i=s.length()
            //此时num=5,跳出循环
            if(num<5) break;
            Min=min(Min,i-j);//更新距离
           //左指针向左移动,直到不完全包含ABCDE字符  
              if((s[j]=='A'||s[j]=='B'||s[j]=='C'||s[j]=='D'||s[j]=='E')
                &&--book[s[j]]==0) num--;
            j++;
        }
        //能拿到的最多宝石为总长度减去包含ABCDE的最短字符串长度
        printf("%d\n",len-Min);
    }
}

其实就是左右指针,先是右指针一直往后移动,直到左右指针之间包含了ABCDE 5个字母之后,然后更新长度,更新完了之后,左指针往右移动,直到左右指针之间已经不完全包含ABCDE之后,右指针又开始像右移动,直到完全包含,又更新,一直下去,直到右指针到了字符串的右边界。

用到了map。介绍:

   Map是c++的一个标准容器,她提供了很好一对一的关系,在一些程序中建立一个map可以起到事半功倍的效果,总结了一些map基本简单实用的操作!
1. map最基本的构造函数;
   map<string , int >mapstring;         map<int ,string >mapint;
   map<sring, char>mapstring;         map< char ,string>mapchar;
   map<char ,int>mapchar;            map<int ,char >mapint;
2. map添加数据;
   map<int ,string> maplive;  
   1.maplive.insert(pair<int,string>(102,"aclive"));
   2.maplive.insert(map<int,string>::value_type(321,"hai"));
   3, maplive[112]="April";//map中最简单最常用的插入添加!
3,map中元素的查找:
   find()函数返回一个迭代器指向键值为key的元素,如果没找到就返回指向map尾部的迭代器。        
   map<int ,string >::iterator l_it;; 
   l_it=maplive.find(112);
   if(l_it==maplive.end())
                cout<<"we do not find 112"<<endl;
   else cout<<"wo find 112"<<endl;
4,map中元素的删除:
   如果删除112;
   map<int ,string >::iterator l_it;;
   l_it=maplive.find(112);
   if(l_it==maplive.end())
        cout<<"we do not find 112"<<endl;
   else  maplive.erase(l_it);  //delete 112;
5,map中 swap的用法:
  Map中的swap不是一个容器中的元素交换,而是两个容器交换;
  For example:
  #include <map>
  #include <iostream>
  using namespace std;
  int main( )
  {
      map <int, int> m1, m2, m3;
      map <int, int>::iterator m1_Iter;
      m1.insert ( pair <int, int>  ( 1, 10 ) );
      m1.insert ( pair <int, int>  ( 2, 20 ) );
      m1.insert ( pair <int, int>  ( 3, 30 ) );
      m2.insert ( pair <int, int>  ( 10, 100 ) );
      m2.insert ( pair <int, int>  ( 20, 200 ) );
      m3.insert ( pair <int, int>  ( 30, 300 ) );
   cout << "The original map m1 is:";
   for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ )
      cout << " " << m1_Iter->second;
      cout   << "." << endl;
   // This is the member function version of swap
   //m2 is said to be the argument map; m1 the target map
   m1.swap( m2 );
   cout << "After swapping with m2, map m1 is:";
   for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ )
      cout << " " << m1_Iter -> second;
      cout  << "." << endl;
   cout << "After swapping with m2, map m2 is:";
   for ( m1_Iter = m2.begin( ); m1_Iter != m2.end( ); m1_Iter++ )
      cout << " " << m1_Iter -> second;
      cout  << "." << endl;
   // This is the specialized template version of swap
   swap( m1, m3 );
   cout << "After swapping with m3, map m1 is:";
   for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ )
      cout << " " << m1_Iter -> second;
      cout   << "." << endl;
}
6.map的sort问题:
  Map中的元素是自动按key升序排序,所以不能对map用sort函数:
  For example:
  #include <map>
  #include <iostream>
  using namespace std;
 int main( )
 {
   map <int, int> m1;
   map <int, int>::iterator m1_Iter;
   m1.insert ( pair <int, int>  ( 1, 20 ) );
   m1.insert ( pair <int, int>  ( 4, 40 ) );
   m1.insert ( pair <int, int>  ( 3, 60 ) );
   m1.insert ( pair <int, int>  ( 2, 50 ) );
   m1.insert ( pair <int, int>  ( 6, 40 ) );
   m1.insert ( pair <int, int>  ( 7, 30 ) );
   cout << "The original map m1 is:"<<endl;
   for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ )
      cout <<  m1_Iter->first<<" "<<m1_Iter->second<<endl;
  
}
  The original map m1 is:
  1 20
  2 50
  3 60
  4 40
  6 40
  7 30
  请按任意键继续. . .
7,   map的基本操作函数:
      C++ Maps是一种关联式容器,包含“关键字/值”对
      begin()          返回指向map头部的迭代器
      clear()         删除所有元素
      count()          返回指定元素出现的次数
      empty()          如果map为空则返回true
      end()            返回指向map末尾的迭代器
      equal_range()    返回特殊条目的迭代器对
      erase()          删除一个元素
      find()           查找一个元素
      get_allocator()  返回map的配置器
      insert()         插入元素
      key_comp()       返回比较元素key的函数
      lower_bound()    返回键值>=给定元素的第一个位置
      max_size()       返回可以容纳的最大元素个数
      rbegin()         返回一个指向map尾部的逆向迭代器
      rend()           返回一个指向map头部的逆向迭代器
      size()           返回map中元素的个数
      swap()            交换两个map
      upper_bound()     返回键值>给定元素的第一个位置
      value_comp()      返回比较元素value的函数

猜你喜欢

转载自blog.csdn.net/qq_36770641/article/details/81350694