STL标准模板库(水题)

目录

A. 数组存数

B. 排序

C. 约瑟夫问题

D. 坐标排序

E. 小X算排名

F. 10进制转D进制

G. 括号匹配

H. 叫号软件

温馨提示:


A. 数组存数

题目描述

今有 N 个数组,初始时,N 个数组均为空。共有 M 次操作,每次在第 X 个数组中加入数字 Y。问最终各数组中有多少数,并将它们排序输出。

比如,输入如下数据:

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

表示有 3 个数组,共有 5 次操作,分别向第 1 个数组存入 33,第 1 个数组存入 2 ,第 1 个数组存入 1,第 2 个数组存入 1,第 3 个数组存入1。

输出如下:

3 1 2 3
1 1
1 1

第 1 行表示:第 1 个数组中有 3 个数,排序结果为1 2 3;

第 2 行表示:第 2 个数组中有 1 个数,排序结果为 1;

第 3 行表示:第 3 个数组中有 1 个数,排序结果为 1;

输入

第一行两个整数 N、M(N≤100000,M≤3000)。

接下来 M 行,每行两个整数 X、Y,含义见试题描述。(1≤X≤N,Y≤1000000000)

输出

共 NN 行;

第 i 行第一个数 SUM,表示第 i 个数组数的个数,接下来 SUM 个数,为排序之后的数组。


代码:

#include<bits/stdc++.h>
using namespace std;
vector<int> a[100100];
int n,m,x,y; 
int main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>x>>y;
		a[x-1].push_back(y); 
	}
	for(int i=0;i<n;i++){
		cout<<a[i].size();
		sort(a[i].begin(),a[i].end());
		for(int j=0;j<a[i].size();j++){
			cout<<' '<<a[i][j];
		}
		cout<<endl;
	}
	return 0;
}

B. 排序

题目描述

给定 N 个数组,要求先对这 N 个数组分别进行排序,然后再根据 N 的数组的字典序对这 NN 个数组进行排序。

输出排序的结果。

输入

第一行一个整数 N,表示数组数。

接下来 N(N≤1000)行,每一行先包含一个整数 C(C≤1000),表示数组的大小,接下来 C 个整数,表示数组中的一个元素。

输出

共 N 行,每行表示一个数组。

样例:

输入

4
1 3
1 1
2 2 1
3 2 3 1

输出

1
1 2
1 2 3
3

代码:

#include<bits/stdc++.h>
using namespace std;
vector<int> a[1005];
int n,c,x;
int main(){
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>c;
		for(int j=0;j<c;j++){
			cin>>x;
			a[i].push_back(x);
		}
		sort(a[i].begin(),a[i].end());
	}
	sort(a,a+n);
	for(int i=0;i<n;i++){
		for(int j=0;j<a[i].size();j++){
			cout<<a[i][j]<<' ';
		}
		cout<<endl;
	}
	return 0;
}

C. 约瑟夫问题

题目描述

约瑟夫问题来源于公元1世纪的犹太历史学家Josephus。问题描述,有n个人(分别以编号1,2,3...n表示)围成一个圆圈,从编号为1的人开始进行1~m正向报数,报到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;如此重复下去,直到所有的人全部出列,求最后一个出列人的编号

输入

输入文件仅有一行包含二个用空格隔开的整数N,M (2≤N≤100000,M≤10^9)。

输出

输出文件仅有一行包含一个整数表示一个整数,表示最后一个人在队列中的编号。

样例:

输入

8 3

输出

7

代码:

#include<bits/stdc++.h>
using namespace std;
vector<int> v;
int n,m,c;
int main(){
	cin>>n>>m;
	for(int i=0;i<n;i++){
		v.push_back(i+1);
	}
	c=-1;
	while(v.size()!=1){
		c=(c+m)%v.size();
		v.erase(v.begin()+c);
		c-=1;
	}
	cout<<v[0];
	return 0;
}

D. 坐标排序

题目描述

输入 n 个不同的坐标,按 x 轴的值从小到大排序,如果 x 相同,则按照 y 排序。

输入

第 1 行是一个整数 n( n≤10000 )。

接下来有 n 行,每行有 2 个整数,代表了 1 个点的坐标。

输出

输出 n 行,每行有 2 个整数,输出排序后的 n 个坐标。

样例:

输入

4
-1 -1
1 1
-1 1
1 -1

输出

-1 -1
-1 1
1 -1
1 1

代码:

#include<bits/stdc++.h>
using namespace std;
pair<int,int> a[10100];
int main(){
	int n,x,y;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>x>>y;
        a[i]=make_pair(x,y);
    }
    sort(a+1,a+n+1);
    for(int i=1;i<=n;i++){
        cout<<a[i].first<<" "<<a[i].second<<endl;
    }
	return 0;
}

E. 小X算排名

题目描述

小 X 很关心自己在学校的表现。

班主任手上有一本“个人得分记录本”,如果一位同学表现好就会加分,表现差则会扣分。学期结束,每位同学都得知了自己的个人得分。小 X 想知道其他同学情况如何,但由于排名不公布,他只好一个个去问班里的其他同学。

现在,小 X 手上有班里共 N 位同学的个人得分,他想知道每位同学的排名 (得分相同则排名相同,见样例),可并不知道该如何计算,希望你帮帮他。

输入

第一行包含一个整数 N 。

接下来 N 行,第 ii 行包含一个整数 Ai​,表示第 i 位同学的得分。

输出

N 行,第 i 行包含一个整数,表示第 i 位同学的排名。

样例:

输入

5
95
100
99
99
96

输出

5
1
2
2
4

代码:

#include<bits/stdc++.h>
using namespace std;
map<int,int,greater<int> > m;
int n,c,a[100100],t;
int main(){
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d",&a[i]);
		if(m.count(a[i])==0){
			m[a[i]]=1;
		}else{
			m[a[i]]++;
		}
	}
	map<int,int>::iterator it;
	for(it=m.begin();it!=m.end();it++){
		t=it->second;
		m[it->first]=c+1;
		c=c+t;
	}
	for(int i=0;i<n;i++){
		printf("%d\n",m[a[i]]);
	}
	return 0;
}

F. 10进制转D进制

题目描述

十进制整数 N 和其他 D(D的值为2到16)进制数的转换是计算机实现计算的基本问题,其解决方法很多,其中一个简单算法基于下列原理:N = (N div d) \times× d + N mod d (其中:div 为整除运算,mod 为求余运算)。简单来说,就是除 D 取余,然后倒过来得到 D 进制的数。

例如:

(1348)10=(10101000100)2
(1348)10=(2504)8
(1000)10=(3E8)16

(请注意:转 16 进制时,用 A 代表余数 10 ,B 代表余数 11 ……)

假设现要编制一个满足下列要求的程序:对于输入的任意一个非负十进制整数(n≤1,000,000,000),打印输出与其等值的 D 进制数。

输入

有两个整数 N 和 D,N 表示要转换的十进制非负整数, D 代表要转换的进制(2到16)

输出

N 进制转 D 进制的结果。

样例:

输入

1348 2

输出

10101000100


代码:

#include<bits/stdc++.h>
using namespace std;
int n,d;
stack<char> s;
string t="0123456789ABCDEF"; 
int main(){
	cin>>n>>d;
	if(n==0){
		cout<<0<<endl;
		return 0;
	}
	while(n!=0){
		s.push(t[n%d]);
		n/=d;
	}
	while(s.size() != 0){
		cout<<s.top();
		s.pop();
	}
	return 0;
}

G. 括号匹配

题目描述

输入一个由()[]四种符号构成的字符串。判断其中的括号是否匹配,是,就输出yes,否则输出no

比如:输入([])([()])[((()))]()[][][]()[]这几个字符串(双引号内部的内容),我们都算是匹配的。

再比如:输入([)([)]([(]))这几个字符串,我们都认为是不匹配的。

输入

一个由()[]四种符号构成的字符串,字符串长度不超过 100 。

输出

如果匹配,请输出yes,如果不匹配,请输出no

样例:

输入

([])

输出

yes

代码:

#include<bits/stdc++.h>
using namespace std;
string x;
stack<char> s;
int main(){
	cin>>x;
	for(int i=0;i<x.size();i++){
		if(x[i]=='('||x[i]=='['){
			s.push(x[i]);
		}else if(x[i]==')'){
			if(s.top()=='(') s.pop();
		}else if(x[i]==']'){
			if(s.top()=='[') s.pop();
		}
	}
	if(s.size()!=0) cout<<"no";
	else cout<<"yes";
	return 0;
}

H. 叫号软件

题目描述

课代表 SW 由于工作失误被扣了奖学金,所以他不得不去某家饭店打工,饭店很火爆,经常没有位置,所以不得不叫号。

他管理叫号软件,一天他不小心把叫号软件的程序删除了,他感觉他完蛋了, 正准备跑路,善良的你不忍心他丢工作你能帮他重新写一个叫号软件吗?

软件有三个指令:

  1. END 为结束程序。

  2. PUSH NAME 为新来了一个名字叫做 NAME 的人排队,NAME 的长度小于等于 10 ,且 NAME 没有重复。

  3. POP 为如果有人在排队则输出当前队列中来的最早的人的名字并将其从队列里删除,如果队列没有人输出 EMPTY

输入

输入可能有若干行(保证不超过 100000),每行一个如下的命令:

PUSH NAMENAME没有空格)。

POP

END

其中,END 命令只会在最后一行出现,并且保证有END。 输入 END 命令后立刻结束程序。

输出

针对每个 POP 命令输出一行,如果有人在排队则输出当前队列中来的最早的人的名字并将其从队列里删除。否则,输出EMPTY

样例:

输入

PUSH LZX
PUSH CQW
POP
PUSH SW
POP
POP
POP
END

输出

LZX
CQW
SW
EMPTY

代码:

#include<bits/stdc++.h>
using namespace std;
queue<string> q;
char a[11],name[11];
int main(){
	while(1){
		scanf("%s",a);
		if(a[0]=='E'){
			break;
		} 
		if(a[1]=='U'){
			scanf("%s",name);
			q.push(name);
		}
		if(a[1]=='O'){
			if(q.empty()){
				cout<<"EMPTY"<<endl;
			}else{
				cout<<q.front()<<endl;
				q.pop();
			}
		}
	}
	return 0;
}

温馨提示:

这些"水题"的题目是作者复制的,代码是作者自己做的,看官们请自己做一遍,锻炼锻炼自己的写代码能力,不了解STL标准模板库的请看——,STL标准模板库(一),STL标准模板库(二),STL标准模板库总结

  • 34
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值