目录
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 由于工作失误被扣了奖学金,所以他不得不去某家饭店打工,饭店很火爆,经常没有位置,所以不得不叫号。
他管理叫号软件,一天他不小心把叫号软件的程序删除了,他感觉他完蛋了, 正准备跑路,善良的你不忍心他丢工作你能帮他重新写一个叫号软件吗?
软件有三个指令:
-
END
为结束程序。 -
PUSH NAME
为新来了一个名字叫做NAME
的人排队,NAME
的长度小于等于 10 ,且NAME
没有重复。 -
POP
为如果有人在排队则输出当前队列中来的最早的人的名字并将其从队列里删除,如果队列没有人输出EMPTY
。
输入
输入可能有若干行(保证不超过 100000),每行一个如下的命令:
PUSH NAME
(NAME
没有空格)。
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标准模板库总结。