(sdau) Summary of the second week.

目录:

一:学习内容
1,二分查找算法
2,algorithm中的全排列库函数
3,容器+迭代器itrator +(::类的限定符)
4,set 和multiset
5,map multimap
6,优先序列
二:用所学解决的问题
三:本周感想

学习内容:

二分查找算法:

STL 中,在 头文件里提供了两个利用二分查找的方法在一个排好序的数组中进行查找。

在一个从小到大的排好序的数组中:

lower_bound(begin,end,value):从数组的 begin 位置到 end-1 位置二分查找第一个大于等于value的数字,找到返回该数字的地址,不存在则返回 end
upper_bound( begin,end,value):从数组的 begin 位置到 end-1 位置二分查找第一个大于 value的数字,找到返回该数字的地址,不存在则返回 end

在一个从大到小的排好序的数组中:

lower_bound( begin,end,value,greater() ):从数组的 begin 位置到 end-1 位置二分查找第一个小于等于 value 的数字,找到返回该数字的地址,不存在则返回 end
upper_bound( begin,end,value,greater() ):从数组的 begin 位置到 end-1 位置二分查找第一个小于 value 的数字,找到返回该数字的地址,不存在则返回 end。
可以通过这两个方法返回的地址减去起始地址 begin得到数字在数组中的下标。

bool cmp(int a,int b)
{
	return a>b;
}
int num[5]={1,4,6,9,8}; 
int pos;
 
sort(num,num+5);//按从小到大 
pos=lower_bound(num,num+5,7)-num;//返回数组中第一个大于或等于7的值的下标 
pos=upper_bound(num,num+5,7)-num;//返回数组中第一个大于7的值的下标
 
sort(num,num+6,cmp);//按从大到小
pos=lower_bound(num,num+5,7,greater<int>())-num;//返回数组中第一个小于或等于7的值的下标 
pos=upper_bound(num,num+5,7,greater<int>())-num;//返回数组中第一个小于7的值的下标
algorithm中的全排列库函数:next_permutation()

在algorithm头文件中有一个next_permutation()库函数。可以给出全排列中的下一个。如果想要输出所有的全排列,需要配合do-while 使用。如果用while的话像下面例子中的1, 2, 3,这个就会丢失。当while循环到最后一个全排列时返回false,循环停止。

#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
	int a[5] = {1, 2, 3};
	do{
	cout << a[0] << " " << a[1] << " " << a[2] << endl;
	} while (next_permutation(a, a+3));
	return 0;
}
stl容器+迭代器itrator +(::类的限定符)

stl中有很多很常用的算法和操作,从简单如 for_each(遍历) 到复杂如 stable_sort(稳定排序)。
容器是stl中的一些模板类,例如:vector(向量)、list(列表)、deque(双向队列)、set(集合)、map(映象)、stack(栈)、queue(队列)、priority_queue(优先队列) 等,通过模版的参数可以指定容器中元素类型。他们都定义了其本身所专有的迭代器,用以存取容器中的元素。
迭代器呢就是对 C++ 中的指针的一般化,用来将算法和容器联系起来,几乎所有的 stl 算法都是通过迭代器来存取元素序列进行工作的。

1,容器:

容器主要分为三类:序列式容器(vector、list、deque)、适配器容器(stack、queue、priority_queue)、关联式容器(set、multiset、map、multimap)
简介如下:(本次总结了解了容器这个总的概念并正在逐步掌握这些容器,以后的总结中也会细节性的描述)

容器名特点
向量(vector)连续存储的元素,位于 < vector >
列表(list)由节点组成的双向链表,每个结点包含着一个元素,位于 < list>
双端队列(deque)连续存储的指向不同元素的指针所组成的数组,位于 < deque>
栈(stack)后进先出的值的排列,位于 < stack>
队列(queue)先进先出的值的排列,位于 < queue>
优先队列(priority_queue)元素的次序是由作用于所存储的值对上的某种谓词决定的的一种队列,位于 < queue>
集合(set)由节点组成的红黑树,每个节点都包含着一个元素,节点之间以某种作用于元素对的谓词排列,没有两个不同的元素能够拥有相同的次序,位于 < set>
多重集合(multiset)允许存在两个次序相等的元素的集合,位于 < set>
映射(map)由键-值对组成的集合,以某种作用于键对上的谓词排列,位于 < map>
多重映射(multimap)允许键对有相等的次序的映射,位于 < map>
2,迭代器:

因为多数容器不支持用下标操作只有少数容器支持(如向量vector)所以有了迭代器这种访问操作方式。
迭代器类型可以用 ’ * '操作符来访问迭代器所指向的元素,以 *iter = 1 为例,假设 it 指向 vector 对象 v 的第一个元素,那么 *iter 与 v[0] 就是指向同一个元素,那么 *iter =1就是将这个元素赋值为 1,与数组相同,迭代器可以使用自增、自减操作符移动迭代器指向容器中邻近元素。
迭代器的常用操作:

*iter对 iter 进行解引用,返回迭代器 iter 指向的元素的引用
iter->men对 iter 进行解引用,获取指定元素中名为 men 的成员,等效于 (*iter).men
++iter、iter++给 iter 加 1,使其指向容器的下一个元素
–iter、iter–给 iter 减 1,使其指向容器的前一个元素
iter1==iter2比较两个迭代器是否相等
iter1!=iter2比较两个迭代器是否不等

几乎每种容器都定义了一对 begin()、end() 函数,用于返回相应的迭代器, begin() 返回的迭代器指向第一个元素, end() 返回的迭代器指向容器中最后一个元素的下一个位置,也就是不指向任何实际的元素,它只是起一个标志的作用,表示已处理完容器中的所有元素,因此不能对它进行解引用(*)或自增(++)操作。

3,类的访问限定符:

因为程序设计恰好学到类所以就写一下自己的理解吧
类有三个访问限定分别是public(公有段数据成员和成员函数),protected(保护段数据成员和成员函数),private(私有段数据成员和成员函数),他们的访问范围依次缩小。
而“::”这个符号就是用来在类的外面去定义类里面的函数所用到的标志符例如:

class Date
{
public:
     int setdate(int year1,int moth1,int day1); 
private:
     int year,moth,day;
};
int Date::setdate(int year1,int moth1,int day1)
{
     year=year1;
     moth=moth1;
     day=day1;
}

当然在“::”这个符号除了在类中使用,在函数中也可以运用,
例如当你定义了一个全局变量A,而在函数里面又定义了一个变量A;大家都知道“强龙比不上地头蛇”的含义,当你要访问全局变量A是就可以使用“::”来访问。
(大概还有别的用法,或者我说的可能不太对,以后再继续完善)

set 和multiset:
1,简介:

set 和 multiset 是集合数据容器,通过链表进行组织,具体实现采用了红黑树的平衡二叉树的数据结构,两者均定义在 头文件中,其会根据特定的规则,自动将元素排序。(一般默认从小到大排序,如果想从大到小排序,运用结构体中的运算符重载 一般重载小于号)

两者不同在于,set 不允许元素重复,而 multiset 允许元素重复。

在插入操作和删除操作上比 vector 快,但查找或添加末尾的元素时会有些慢。

2,定义:

set setname;multiset multisetname;

1)set < type > s;multiset < type >s:产生一个空的 set或者multiset,其中不含任何元素
2)set < type > s(op):以 op 为排序准则,生成一个 set/multiset
3)set < type > s1(s2):产生s2 的副本,所有元素均被复制到s1中
4)set < type > s(beg, end):以迭代器的区间 [beg; end] 内的元素产生一个 set/multiset
5)set s(beg, end, op):以 op 为排序准则,利用迭代器的区间 [beg; end] 内的元素生成一个 set/multiset

3,基本操作:

对于 set s 的基本操作有:

1)s.size():返回容器大小
2)s.empty():返回容器是否为空。
3)s.clear():清空容器
4)s.count(elem):返回元素值为 elem 的元素的个数
5)s.insert(elem) :加入一个 elem 副本,返回新元素位置
6)s.erase(elem):移除与 elem 元素相等的所有元素,返回被移除的元素个数

4,迭代器操作:

对于 set s 的迭代器 it 的操作有:

1)s.begin():返回一个双向迭代器,指向第一个元素
2)s.end():返回一个双向迭代器,指向最后一个元素的下一 个位置
3)s.erase(it):移除迭代器 it 所指位置上的元素,无返回值
4)s.lower_bound(elem):返回 elem 的第一个可安插的位置,即元素值 >= elem 的第一个元素位置
5)s.upper_bound(elem):返回 elem 的最后一个可安插的位置,即元素值 > elem 的第一个元素的位置

注意:当要在 multiset 中存储自定义数据类型时,除了要写自定义类型的存储结构外,还要写一个比较函数 cmp 来告诉 multiset 如何去比较自定义类型。

struct Node
{
    int x,y;
};
struct cmp
{
    bool operator()(const Node &a,const Node &b)
    {
        if(a.x==b.x)
            return a.y<b.y;
        return a.x<b.x;
    }
};
multiset<Node,cmp> s;
map multimap:
1,简介:

map 和 multimap 是映射数据容器,两者均定义与 头文件中,所有元素都会根据元素的键值自动排序,map的所有元素都是pair,pair的第一个元素被视为键值,第二个元素为实值。键值和实值的数据类型是可以不同的,区别在于,map不允许两个元素有相同的键值,但multimap可以。

2,定义:

map <type1, type2> mapName、multimap <type1, type2> multimapName

map<type1,type2> m产生一个空的 map/multimap,其中不含任何元素
map<type1,type2> m(op)以 op 为排序准则,产生一个空的 map/multimap
map<type1,type2> m1(m2)产生某个 map/multimap 的副本,所有元素均被复制
map<type1,type2> m(beg, end)以迭代器区间 [beg; end] 内的元素产生一个 map/multimap
map<type1,type2> m(beg, end, op):以 op 为排序准则,以迭代器区间 [beg; end] 内的元素生成一个map/multimap
3,基本操作:
m.size()返回容器大小
m.empty()返回容器是否为空
m.clear()清空容器
m.count(key)返回键值等于 key 的元素的个数
m.erase(elem)移除键值为 elem 的所有元素,返回个数,对 map 来说非 0 即 1
m[key] = value查找的时候若没有键值为 key 的元素,则插入一个键值为 key 的新元素,实值为默认值(一般为 0)

m.insert(elem)|用于插入元素,其有三种形式
1):运用 value_type 插入:
map<string, float> m;
m.insert(map<string, float>:: value_type (“Robin”, 22.3));
2)运用 pair<>:
m.insert(pair<string, float>(“Robin”, 22.3));
3)运用 make_pair():
m.insert(make_pair(“Robin”, 22.3));

4,迭代器操作

对于 map m 的迭代器 it 的操作有:

m.begin()返回一个双向迭代器,指向第一个元素
m.end()返回一个双向迭代器,指向最后一个元素的下一个位置
m.erase(it)移除迭代器 it 所指位置上的元素,并返回指向下一个元素对的迭代器
m.lower_bound(key)返回键值等于 key 的元素的第一个可安插的位置
m.upper_bound(key)返回键值等于key的元素的最后一个可安插的位置
优先排序:

priority_queue 优先队列,其底层是用堆< queue>(下次总结补充堆栈的部分)来实现的。在优先队列中,队首元素一定是当前队列中优先级最高的那一个。

在优先队列中,没有 front() 函数与 back() 函数,而只能通过 top() 函数来访问队首元素,就是堆顶元素,也就是优先级最高的元素。
对priority_queue< int > q基本操作有:
q.empty() 如果队列为空返回真
q.pop() 删除对顶元素
q.push() 加入一个元素
q.size() 返回优先队列中拥有的元素个数
q.top() 返回优先队列对顶元素

priority_queue 默认为大顶堆,即堆顶元素为堆中最大元素

如果我们想要用小顶堆的话需要增加使用两个参数:
priority_queue< int, vector, greater > q; // 小顶堆
priority_queue< int, vector, less > q; // 大顶堆

其中第二个参数( vector ),是来承载底层数据结构堆的容器,第三个参数( less ),则是一个比较类,less 表示数字大的优
先级高,而 greater 表示数字小的优先级高。

用所学解决的问题:

A - A

Description
“临流揽镜曳双魂 落红逐青裙 依稀往梦幻如真 泪湿千里云”
在MCA山上,除了住着众多武林豪侠之外,还生活着一个低调的世外高人,他本名逐青裙,因为经常被人叫做"竹蜻蜓",终改名逐青,常年隐居于山中,不再见外人.根据山上附近居民所流传的说法,逐青有一个很奇怪的癖好,从他住进来那天开始,他就开始在他的院子周围种竹子,第1个月种1根竹子,第2个月种8根竹子,第3个月种27根竹子…第N个月就种(N^3)根竹子.他说当他种下第X根竹子那一刻,就是他重出江湖之时!告诉你X的值,你能算出逐青的复出会是在第几个月吗?

Input
首先输入一个t,表示有t组数据,跟着t行.每行是一个整数X,X < 1000000000
Output
输出一个整数n,表示在第n个月复出
Sample Input
3 1 2 10
Sample Output
1 2 3
很简单的题意,运用刚学的lower_bound刚刚好;

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long ll;
int main()
{
    ll f[1005],x,t; 
    scanf("%lld",&t);
    for(int i=1;i<=1002;i++)
    f[i]=pow(i,3)+f[i-1];
    while(t--)    
    {
        scanf("%lld",&x);
        int t=lower_bound(f,f+1002,x)-f;
        printf("%d\n",t);
    }
}
B-B

Description
Soundex coding groups together words that appear to sound alike based on their spelling. For example, “can” and “khawn”, “con” and “gone” would be equivalent under Soundex coding.
Soundex coding involves translating each word into a series of digits in which each digit represents a letter:

  1 represents B, F, P, or V

  2 represents C, G, J, K, Q, S, X,  or Z

  3 represents D or T

  4 represents L

  5 represents M or N

  6 represents R

The letters A, E, I, O, U, H, W, and Y are not represented in Soundex coding, and repeated letters with the same code digit are represented by a single instance of that digit. Words with the same Soundex coding are considered equivalent.

Input
Each line of input contains a single word, all upper case, less than 20 letters long.

Output
For each line of input, produce a line of output giving the Soundex code.

Sample Input
KHAWN
PFISTER
BOBBY
Sample Output
25
1236
11
题目理解:给定大写英文字母映射的数字,输入字符串然后输出字符串中给定字母的映射数字:

思路很简单,运用char为键值,int为实值的映射即可;

#include<iostream>
#include<map>
using namespace std;
 
int main()
{
	map<char,char> m;
	
	m['B'] = m['F'] = m['P'] = m['V'] = '1';
    m['C'] = m['G'] = m['J'] = m['K'] = m['Q'] = m['S'] = m['X'] = m['Z'] = '2';
    m['D'] = m['T'] = '3';
    m['L'] = '4';
    m['M'] = m['N'] = '5';
    m['R'] = '6';
    m['A'] = m['E'] = m['I'] = m['O'] = m['U'] = m['H'] = m['W'] = m['Y'] = '0';
	
	string s;
	char tmp,last;
	
	while(cin>>s)
	{
		last='\0';
		int i=0;
		while(s[i])
		{
			tmp=m[s[i]];
			if(tmp!='0')
				if(tmp!=last)
					cout<<tmp;
			last=tmp;//有两种可能 
			i++; 
		} 
		cout<<endl;
	} 
	
	return 0;
} 
 
C-C

题目描述:
读入n个数,要求按照从小到大的顺序输出出现的不同数字。

输入:
第一行读入一个 n ( 0<n<=1000000)

第二行读入n个整数k (-2^31 <= k < 2^31 )

输出:
按从小到大的顺序输出不同的数字

样例输入
5
1 3 1 99999999 3
样例输出
1 3 99999999

#include<iostream>
#include<set>
using namespace std;
typedef long long ll;
int main()
{
    set<ll> a;
    set<ll>::iterator it;
    int n;
    cin >> n;
    ll k;
    for(int i = 1 ; i <= n ; i++)
    {
        cin >> k;
        it = a.find(k);//查找k元素,如果有返回该元素地址,如果没有返回无效地址
        if(it == a.end())//a.end就是个标志,没有实际意义
        a.insert(k);
    }
    for(it = a.begin();it != a.end();it++)
        cout << *it << " ";
    return 0;
}
D-D

Problem Description
Because of the wrong status of the bicycle, Sempr begin to walk east to west every morning and walk back every evening. Walking may cause a little tired, so Sempr always play some games this time.
There are many stones on the road, when he meet a stone, he will throw it ahead as far as possible if it is the odd stone he meet, or leave it where it was if it is the even stone. Now give you some informations about the stones on the road, you are to tell me the distance from the start point to the farthest stone after Sempr walk by. Please pay attention that if two or more stones stay at the same position, you will meet the larger one(the one with the smallest Di, as described in the Input) first.
Input
In the first line, there is an Integer T(1<=T<=10), which means the test cases in the input file. Then followed by T test cases.
For each test case, I will give you an Integer N(0<N<=100,000) in the first line, which means the number of stones on the road. Then followed by N lines and there are two integers Pi(0<=Pi<=100,000) and Di(0<=Di<=1,000) in the line, which means the position of the i-th stone and how far Sempr can throw it.
Output
Just output one line for one test case, as described in the Description.
Sample Input
2
2
1 5
2 4
2
1 5
6 6
Sample Output
11
12

题目理解:奇数石头要丢掉偶数石头不动

#include <iostream>
#include <stdio.h>
#include <string.>
#include <queue>
using namespace std;
struct node
{
    int m,n;
    friend bool operator<(node a,node b)
    {
        if(a.m!=b.m)
        return a.m>b.m;//最小值优先
        else return a.n>b.n;
    }
};
int main()
{
    int t;
    while(cin>>t)
    {
        while(t--)
        {
            int n;
            cin>>n;
            int i;
            priority_queue<node>q;
            node a,b;
            for(i=0;i<n;i++)
            {
                int c,d;
                cin>>c>>d;
                a.m=c;
                a.n=d;
                q.push(a);
            }
            int z=0;//判断石头是否是偶数个;
            int sum=0;
            while(!q.empty())
            {
                z++;
                a=q.top();
                sum=a.m;
                if(z%2==0)
                {
                    q.pop();
                }
                else
                {
                    b.m=a.m+a.n;
                    b.n=a.n;
                    q.pop();
                    q.push(b);
                }
            }
            cout<<sum<<endl;
        }
    }
    return 0;
}

本周感想:

学到了蛮多东西,打了周四的dv3比赛,dv3对我来说都有点难,今晚就整理了这些总结,没打今晚的比赛,明天再去看题把。
stl中的栈和队列还没总结,下次一定,很多东西都是有所关联的,学的越多以后写的代码越简洁,越精炼,打比赛也会更快,哦对了,打个比赛英语题目差点把我带走,英语果然很重要,下周继续努力!

 Youth means limitless possibilities.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值