寒假试水1总结

目录

STL

试水题A

试水题B:

试水题C

试水题D:

试水题E:

试水题F:


需要掌握STL

1:map:

map是STL的一个关联容器,它提供一对一(其中第一格称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性:
map内部的实现自建一棵红黑树(一种非严格意义的平衡二叉树),这棵树具有对数据自动排序的功能。

比如在一个班级中,每个学生的学号跟它的姓名就存在着一一对应的关系,这个模型就可以用map轻易的描述,很明显学号用int描述,姓名用字符串描述(本篇文章中不用char*来描述字符串,而是采用STL中的String来描述)。

a:声明方式:

map<int,string>mapStudent;或map<String,int>mapStudent;

b:数据的插入:

第一种:用insert函数插入pair数据

map<int;string>mapStudent;

mapStudent.insert(pair<int,string>(1,"student-one"));

第二种:用insert函数插入value-type数据:

map<int,string>mapStudent;

mapStudent.insert(map<int,string>::value_type(1,"student_one"));

第三种:用数组方式插入数据

map<int,string>mapStudent;

mapStudent[1]="student_one";

map<int,string>mapStudent;
sting s; 插入就用m[s]=1或者m[s]++之类;

以上三种方法,虽然都可以实现数据的插入,但是它们是有区别的 ,当然第一种和第二种在效果上是完成一样的,用insert函数插入数据,在数据的插入上涉及到集合的唯一性这个概念,即用map这个关键字时,insert是不能再插入这个数据的,但是用数组的方式就不同了,它可以覆盖以前关键字对应的值。

c:map的大小

要想知道已经插入了多少数据,可以用size函数:
 

int size = Student.size();

d:数据的查找(包括判断这个关键字是否在map中出现):

第一种:用count函数来判断关键字是否出现,但无法确定数据出现的位置

第二种:用find函数来定位数据据出现的位置它返回的第一个迭代器,当数据出现时,它返回函数所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器。

第三种:

lower_bound函数用法,这个函数来返回要查找关键字的下界。

upper_bound函数用法,这个函数来返回要查找关键字的上界。

例如:map中已经插入了1,2,3,4的话,如果lower_bound(2)的话,返回的2,而upper_bound(2)的话,就返回的3.

equal_ranger函数返回一个pair,pair里面第一个变量是Lower_bound返回的迭代器,pair里面第二个迭代器是Upper_bound返回的迭代器,如果这两个迭代器相等的话,则说明map中不出现这个关键字,程序说明:

        

mapPair = mapStudent.equal_range(2);
if(mapPair。first==mapPair.second)
cout<<"Dont find "<<endl;

e:数据的清空与判空

清空map中的数据可以用clear函数,判定map中是否有数据可以用empty()函数,它返回true则说明map空

f:数据的删除:

这里要用erase函数,它有三个重载了的函数

迭代器删除
iter = mapStudent.find("123");
mapStudent.erase(iter);
 
用关键字刪除
int n = mapStudent.erase("123"); //如果刪除了會返回1,否則返回0
 
用迭代器范围刪除 : 把整个map清空,成片删除
mapStudent.erase(mapStudent.begin(), mapStudent.end());
等同于mapStudent.clear()

成片删除需要注意的是,也是STL的特性,删除区间是一个左闭右开的集合。

g:map的基本操作函数:

     C++ maps是一种关联式容器,包含“关键字/值”对

     begin()         返回指向map头部的迭代器

     clear()        删除所有元素

     count()         返回指定元素出现的次数, (帮助评论区理解: 因为key值不会重复,所以只能是1 or 0)

     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的函数

试水题A

A题可以使用 map解答

A. Diverse Team

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

There are nn students in a school class, the rating of the ii-th student on Codehorses is aiai. You have to form a team consisting of kk students (1≤k≤n1≤k≤n) such that the ratings of all team members are distinct.

If it is impossible to form a suitable team, print "NO" (without quotes). Otherwise print "YES", and then print kk distinct numbers which should be the indices of students in the team you form. If there are multiple answers, print any of them.

Input

The first line contains two integers nn and kk (1≤k≤n≤1001≤k≤n≤100) — the number of students and the size of the team you have to form.

The second line contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤1001≤ai≤100), where aiai is the rating of ii-th student.

Output

If it is impossible to form a suitable team, print "NO" (without quotes). Otherwise print "YES", and then print kk distinct integers from 11 to nn which should be the indices of students in the team you form. All the ratings of the students in the team should be distinct. You may print the indices in any order. If there are multiple answers, print any of them.

Assume that the students are numbered from 11 to nn.

Examples

input

Copy

5 3
15 13 15 15 12

output

Copy

YES
1 2 5 

input

Copy

5 4
15 13 15 15 12

output

Copy

NO

input

Copy

4 4
20 10 40 30

output

Copy

YES
1 2 3 4 

Note

All possible answers for the first example:

  • {1 2 5}
  • {2 3 5}
  • {2 4 5}

Note that the order does not matter.

试水题A题map题解:

Problem - 988A - Codeforces

#include<iostream>
#include<map>
using namespace std;
map<int, int> p;
int main()
{
    int n,k;
    cin >> n >> k;
     for(int i = 1; i <= n; i++){
         int a;
         cin >> a;
         p[a] = i;
     }
     if(p.size() < k){
         cout << "NO";
     }
     else{
        cout <<"YES"<<endl;
        map<int, int>::iterator it;
        for(it = p.begin();it!=p.end(); it++)
        {
            cout << (it->second) <<" ";
            if(--k == 0)
            {
                break;
            }
        }
     }
}

试水题B:

B题使用map比较容易

Equal Sums

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given kk sequences of integers. The length of the ii-th sequence equals to nini.

You have to choose exactly two sequences ii and jj (i≠ji≠j) such that you can remove exactly one element in each of them in such a way that the sum of the changed sequence ii (its length will be equal to ni−1ni−1) equals to the sum of the changed sequence jj (its length will be equal to nj−1nj−1).

Note that it's required to remove exactly one element in each of the two chosen sequences.

Assume that the sum of the empty (of the length equals 00) sequence is 00.

Input

The first line contains an integer kk (2≤k≤2⋅1052≤k≤2⋅105) — the number of sequences.

Then kk pairs of lines follow, each pair containing a sequence.

The first line in the ii-th pair contains one integer nini (1≤ni<2⋅1051≤ni<2⋅105) — the length of the ii-th sequence. The second line of the ii-th pair contains a sequence of nini integers ai,1,ai,2,…,ai,niai,1,ai,2,…,ai,ni.

The elements of sequences are integer numbers from −104−104 to 104104.

The sum of lengths of all given sequences don't exceed 2⋅1052⋅105, i.e. n1+n2+⋯+nk≤2⋅105n1+n2+⋯+nk≤2⋅105.

Output

If it is impossible to choose two sequences such that they satisfy given conditions, print "NO" (without quotes). Otherwise in the first line print "YES" (without quotes), in the second line — two integers ii, xx (1≤i≤k,1≤x≤ni1≤i≤k,1≤x≤ni), in the third line — two integers jj, yy (1≤j≤k,1≤y≤nj1≤j≤k,1≤y≤nj). It means that the sum of the elements of the ii-th sequence without the element with index xx equals to the sum of the elements of the jj-th sequence without the element with index yy.

Two chosen sequences must be distinct, i.e. i≠ji≠j. You can print them in any order.

If there are multiple possible answers, print any of them.

Examples

input

Copy

2
5
2 3 1 3 2
6
1 1 2 2 2 1

output

Copy

YES
2 6
1 2

input

Copy

3
1
5
5
1 1 1 1 1
2
2 3

output

Copy

NO

input

Copy

4
6
2 2 2 2 2 2
5
2 2 2 2 2
3
2 2 2
5
2 2 2 2 2

output

Copy

YES
2 2
4 1

Note

In the first example there are two sequences [2,3,1,3,2][2,3,1,3,2] and [1,1,2,2,2,1][1,1,2,2,2,1]. You can remove the second element from the first sequence to get [2,1,3,2][2,1,3,2] and you can remove the sixth element from the second sequence to get [1,1,2,2,2][1,1,2,2,2]. The sums of the both resulting sequences equal to 88, i.e. the sums are equal

Problem - 988C - Codeforces

给 n 个数组,找出两个数组,这两个数组各删除一个数字后,使得两个数组的和相同.

map题解:

#include <iostream>
#include<map>
typedef long long ll;
using namespace std;
struct node
{
    int x,y;
};
ll a[300000];
int main()
{
    ll n,m,i,j,sum,x,k,a1,a2,a3,a4;
    node w;
    map<ll,node> q;
    cin>>n;
    int f = 0;
    for(k=1;k<=n;k++)
    {
        scanf("%lld",&m);
        sum=0;
        for(i=1;i<=m;i++)
        {
            scanf("%lld",&a[i]);
            sum+=a[i];
        }
        for(i=1;i<=m;i++)
        {
            if(f) break;
            x = sum - a[i];
            if(q.count(x))
            {
                w = q[x];
                if(w.x != k)
                {
                    f=1;
                    a1 = k;
                    a2 = i;
                    a3 = w.x;
                    a4 = w.y;
                }
            }
            else
            {
                w.x = k;
                w.y = i;
                q[x] = w;
            }
        }
    }
    if(f)
    {
        printf("YES\n");
        printf("%lld %lld\n%lld %lld\n",a1,a2,a3,a4);
    }
    else
    printf("NO\n");
    return 0;
}

试水题C

传送门-试水题C

本题个人感觉比较简单就是个字符串题

题解

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct node
{
    int l;
    char a[110];
} q[110];
int cmp(node x,node y)
{
    return x.l<y.l;
}
int main()
{
    int n;
    while(scanf("%d",&n))
    {
        int flag=0;
        for(int i=0; i<n; i++)
        {
            scanf("%s",&q[i].a);
            q[i].l=strlen(q[i].a);
        }
        sort(q,q+n,cmp);
        for(int i=0; i<n-1; i++)
        {
            if(strstr(q[i+1].a,q[i].a)==NULL)
            {
                flag=1;
                break;
            }
        }
        if(flag==1)
            printf("NO\n");
        else
        {
            printf("YES\n");
            for(int i=0; i<n; i++)
                printf("%s\n",q[i].a);
        }
        return 0;
    }
    return 0;
}

试水题D:

Problem - 978B - Codeforces

本题也比较简单,是我感觉最简单的一个题,也是字符串题

#include<iostream>
#include<string>
using namespace std;
char string1[100];
int main()
{
	int i=0;
	int n = 0;
	int ans = 0;
	scanf("%d", &n);

	scanf("%s", string1);
	for (i = 0; i<n - 2; i++)
	{
		if (string1[i] == 'x' && string1[i + 1] == 'x' && string1[i + 2] == 'x')
		{
			ans++;
		}
	}
	printf("%d\n", ans);
	return 0;
}

试水题E:

Problem - 978C - Codeforces

C. Letters

time limit per test

4 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

There are nn dormitories in Berland State University, they are numbered with integers from 11 to nn. Each dormitory consists of rooms, there are aiai rooms in ii-th dormitory. The rooms in ii-th dormitory are numbered from 11 to aiai.

A postman delivers letters. Sometimes there is no specific dormitory and room number in it on an envelope. Instead of it only a room number among all rooms of all nn dormitories is written on an envelope. In this case, assume that all the rooms are numbered from 11 to a1+a2+⋯+ana1+a2+⋯+an and the rooms of the first dormitory go first, the rooms of the second dormitory go after them and so on.

For example, in case n=2n=2, a1=3a1=3 and a2=5a2=5 an envelope can have any integer from 11 to 88 written on it. If the number 77 is written on an envelope, it means that the letter should be delivered to the room number 44 of the second dormitory.

For each of mm letters by the room number among all nn dormitories, determine the particular dormitory and the room number in a dormitory where this letter should be delivered.

Input

The first line contains two integers nn and mm (1≤n,m≤2⋅105)(1≤n,m≤2⋅105) — the number of dormitories and the number of letters.

The second line contains a sequence a1,a2,…,ana1,a2,…,an (1≤ai≤1010)(1≤ai≤1010), where aiai equals to the number of rooms in the ii-th dormitory. The third line contains a sequence b1,b2,…,bmb1,b2,…,bm (1≤bj≤a1+a2+⋯+an)(1≤bj≤a1+a2+⋯+an), where bjbj equals to the room number (among all rooms of all dormitories) for the jj-th letter. All bjbj are given in increasing order.

Output

Print mm lines. For each letter print two integers ff and kk — the dormitory number ff (1≤f≤n)(1≤f≤n) and the room number kk in this dormitory (1≤k≤af)(1≤k≤af) to deliver the letter.

Examples

input

Copy

3 6
10 15 12
1 9 12 23 26 37

output

Copy

1 1
1 9
2 2
2 13
3 1
3 12

input

Copy

2 3
5 10000000000
5 6 9999999999

output

Copy

1 5
2 1
2 9999999994

Note

In the first example letters should be delivered in the following order:

  • the first letter in room 11 of the first dormitory
  • the second letter in room 99 of the first dormitory
  • the third letter in room 22 of the second dormitory
  • the fourth letter in room 1313 of the second dormitory
  • the fifth letter in room 11 of the third dormitory
  • the sixth letter in room 1212 of the third dormitory

使用STL中的lower_bound,虽然代码短,但是不好做

//本内容转载至http://m.biancheng.net/view/7521.html
lower_bound() 函数用于在指定区域内查找不小于目标值的第一个元素。也就是说,使用该函数在指定范围内查找某个目标值时,最终查找到的不一定是和目标值相等的元素,还可能是比目标值大的元素。

lower_bound() 函数定义在<algorithm>头文件中,其语法格式有 2 种,分别为:
//在 [first, last) 区域内查找不小于 val 的元素
ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last,
                             const T& val);
//在 [first, last) 区域内查找第一个不符合 comp 规则的元素
ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last,
                             const T& val, Compare comp);
其中,first 和 last 都为正向迭代器,[first, last) 用于指定函数的作用范围;val 用于指定目标元素;comp 用于自定义比较规则,此参数可以接收一个包含 2 个形参(第二个形参值始终为 val)且返回值为 bool 类型的函数,可以是普通函数,也可以是函数对象。
实际上,第一种语法格式也设定有比较规则,只不过此规则无法改变,即使用 < 小于号比较 [first, last) 区域内某些元素和 val 的大小,直至找到一个不小于 val 的元素。这也意味着,如果使用第一种语法格式,则 [first,last) 范围的元素类型必须支持 < 运算符。

此外,该函数还会返回一个正向迭代器,当查找成功时,迭代器指向找到的元素;反之,如果查找失败,迭代器的指向和 last 迭代器相同。

再次强调,该函数仅适用于已排好序的序列。所谓“已排好序”,指的是 [first, last) 区域内所有令 element<val(或者 comp(element,val),其中 element 为指定范围内的元素)成立的元素都位于不成立元素的前面。

AC代码 

思路:用a数组存每栋宿舍楼的最大宿舍编号,然后lower_bound找出在第栋宿舍,减去前一栋宿舍的最大编号

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int Max=2e5+100;
ll a[Max];
int main()
{
    ll n,m,x,pos;
    cin>>n>>m;
    for(int i=1; i<=n; i++)
    {
        cin>>x;
        a[i]=a[i-1]+x;
    }
    while(m--)
    {
        cin>>x;
        pos=lower_bound(a+1,a+1+n,x)-a-1;
        cout<<pos+1<<" "<<x-a[pos]<<endl;
    }
    return 0;
}

试水题F:

Remove Duplicates - CodeForces 978A - Virtual Judge

Problem - 978A - Codeforces

比较容易,数列去重,记下每个数字出现的次序和顺序,最后进行输出

AC代码

#include<iostream>
using namespace std;

int main()
{
	int n;
	while(cin>>n)
	{   int b[10000]={0};
	    int a[10000];
	    int ans[100];
	    int c=0;
	    for(int i=0;i<n;i++)
		{
			cin>>a[i];
			 b[a[i]]++;
		 }
		 for(int i=0;i<n;i++)
		 {
		 	if(b[a[i]]==1)
		 	{
		 		ans[c++]=a[i];

			 }
			 else
			 b[a[i]]--;

		 }
		 cout<<c<<endl;
		 for(int j=0;j<c;j++)

		 {
		 	cout<<ans[j]<<" ";

		 }
		 cout<<endl;

	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值