问题 A: 我有一个vector
题目描述
作为一个程序媛/猿,或许大家都有头被按在键盘上的经历。
边总突然想知道自己的头在键盘上按出来的字母有没有规律,于是他打算统计出被按出来的乱码中每个字母出现的位置。
给出字符串和要查询的字母,问要查询的字母出现过的位置。
输入
多组测试样例
每行为一个不知道有多长的字符串 s ,然后是一个字符表示 c 要查询的字母,中间用空格隔开。
保证字符串中只有小写字母。
输出
输出要查询的字母在字符串中出现过的位置,字符串下标从一开始。
如果要查询的字母不在字符串中,输出 NO
样例输入
asdfghjkls s
abcdef x
样例输出
2 10
NO
#include <vector>
#include <iostream>
#include<cstring>
#include<map>
using namespace std;
int main() {
string s;
char c;
while(cin>>s>>c){
int flag=1;
string::iterator it; //字符串的迭代器
vector<int> v; //定义一个vectorr
for(it=s.begin();it!=s.end();++it){
if(*it==c)
v.push_back(flag) ;
flag++; //位置
}
if(!v.empty()){ //如果不为空输出vector里的存储
vector<int>::iterator l;
for(l=v.begin();l!=v.end();l++)
cout<<*l<<" ";
cout<<endl;
}
else //如果vector为空,说明没有相应位置
cout<<"NO"<<endl;
}
return 0;
}
问题 B: 珊珊的选择恐惧症
时间限制: 1 Sec 内存限制: 128 MB
题目描述
珊珊是个喜欢买买买的女孩子,今天她想去商店买衣服,但她有选择恐惧症不知道去哪一家店,于是她想了个办法。她给n个商店编号(编号为 1~n),从第 1 家店开始数,一直数到 m,数到 m 的店不在她的选择范围内,剩下的店再接着从 1 开始数。这样一直重复,最后剩下哪家店,她就去那家店买衣服。你能告诉珊珊她该去编号为多少的店买衣服么?
输入
有多组测试样例
每组测试样例包含两个数字 n 和 m
读到0 0为止
输出
对每个测试样例输出一个店的编码(最后一行除外)
样例输入
4 2
27 8
0 0
样例输出
1
7
题意分析:将第m个商店排除后,继续将下一个作为1,再数m个,再排除。直到只剩一个
遇到末尾时返回头部继续数
#include <vector>
#include <iostream>
#include<cstring>
#include<list>
#include<queue>
using namespace std;
int main() {
vector<int> s; //定义一个vector
int n,m;
while(1){
cin>>n>>m;
if(n==0&&m==0) break;
s.clear();
for(int i=1;i<=n;i++)
s.push_back(i);
vector<int>::iterator it=s.begin(); //定义一个迭代器
while(s.size()>1){ //只剩一个时退出循环
for(int i=1;i<m;i++){ //数m个
it++; //相应迭代器的位置也加m
if(it==s.end()) it=s.begin(); //当遇到末尾时返回队头
}
it=s.erase(it); //然后删除这个位置上的值 erase返回的是删除值的下一个位置
if(it==s.end()) it=s.begin(); //当删除后,遇到末尾时返回队头
}
cout<<s.front()<<endl; //输出 因为只有一个元素,所以可以用front
}
return 0;
}
问题 C: 红红的新版星星消消乐
题目描述
红红昨天玩了星星消消乐,但是特别不喜欢星星消消乐里没办法一次拿到所有星星的问题,所以他今天决定玩一个新的消消乐版本,号称队列消消乐, 即消消乐只能拿队首元素出来判断能不能消除,但是队尾不能进人,所以红红决定拿两个队列来存星星。星星可以消灭的判断依据是序号相同,即可消灭。比如两队星星, 1 2 3 2 1 和 1 3 2 2 1,拿出队首的1,可以消灭,于是可消灭星星+2剩余两个队列中的元素是 2 3 2 1和 3 2 2 1, 第二次2和3无法消灭,那就扔掉第一队的星星,红红是个有大局观的人,当第一队列为空时无法继续消灭;则结束
本题要求用 STL库做
queue 队列 队首元素 q.front();
输入
本题有多组样例
第一个数字n 代表两个队列各有多少个数字( 0 < n <= 10000)
第二行和第三行各有n 个数字, 每个数字的大小在 [0 1000]
输出
输出消灭星星的总数
样例输入
5
1 2 3 2 1
1 3 2 2 1
5
1 1 1 1 1
2 2 2 2 2
样例输出
6
0
题意
#include <vector>
#include <iostream>
#include<cstring>
#include<list>
#include<queue>
using namespace std;
int main() {
int n;
int x;
while(cin>>n){
int flag=0;
queue<int> q1; //定义两个队列
queue<int> q2;
for(int i=0;i<n;i++){ //输入
cin>>x;
q1.push(x);
}
for(int j=0;j<n;j++){ //输入
cin>>x;
q2.push(x);
}
while(!q1.empty()){ //q1为空时退出循环
if(q1.front()==q2.front()){ //如果q1的头等于q2的头则两个都消
q1.pop();
q2.pop();
flag+=2; //得分+2
}else{ //如果q1的头不等于q2的头则消除q1的头
q1.pop();
}
}
cout<<flag<<endl; //输出得分
}
return 0;
}
问题 D: 小磊的求助
题目描述
小雪和小磊出去吃饭,但是老是有人插队,当然也有人离开
每当发现有人插队的时候,小雪就会让小磊去看一下前面人的排队码并报给她
你能帮帮小磊么?
输入
输入两个数字 t ( t ≤ 10),N(N ≤ 100)
接下来有N个正整数 表示一开始小雪前面 N 个人的排队码Ai (1≤ Ai ≤108)
接下有 t 行输入,输入有两种形式
- insert i j : i 和 j 为正整数,表示有拿着 j 排队码的人插队到了第i 个 人前面
- leave i :i 为正整数,表示第i个人离开
输出
行数不定,每次有人插队时,输出他插队后所有人的排队码
样例输入
2 9
11 22 33 44 55 66 77 88 99
leave 1
insert 5 37
样例输出
22 33 44 55 37 66 77 88 99
#include <vector>
#include <iostream>
#include<cstring>
#include<list>
#include<queue>
using namespace std;
int main() {
vector<int> c;
int t,n,x;
scanf("%d %d",&t,&n);
for(int i=0;i<n;i++){
cin>>x;
c.push_back(x); //输入初始排队码
}
while(t--){ //t行操作
string s;
cin>>s;
if(s[0]=='l'){ //如果是离开,
int i;
cin>>i;//第几个人离开
vector<int>::iterator it=c.begin(); //队头
c.erase(it+i-1); //删除 vector有erase,list没有
}else{
int i,j;
cin>>i>>j;
vector<int>::iterator it=c.begin(); //队头
c.insert(it+i-1,j); //插入j w位置为it+i-1
vector<int> ::iterator it2;
for(it2=c.begin();it2!=c.end();it2++){ //每次插队后,输出所有
cout<<*it2<<" ";
}
}
}
return 0;
}
问题 E: 数字去重
题目描述
输入n(n < 10000)个数字,要求每个数子只能输出一次,且输出结果为非递减序。
输入
输入包含多组测试数据,每组测试样例都包含两行,第一行为一个整数n,表示有n个数字,接下一行包含n个数字,两个数字之间用空格分开。
输出
输出包括一行,按照非递减序输出所有数字,并且所有数字只出现一次,两个数字之间用空格分开。
样例输入
4
1 2 3 1
5
1 1 1 1 2
样例输出
1 2 3
1 2
#include <iostream>
#include<cstring>
#include<list>
#include<stack>
using namespace std;
int main() {
int n,x;
while(cin>>n){
list<int> l;
list<int> s;
while(n--){
cin>>x;
l.push_back(x); //输入n个数
}
l.sort(); //排序
list<int>::iterator it; //定义迭代器
for(it=l.begin();it!=l.end();it++){
if(s.empty()) //l的第一个元素入s
s.push_back(*it);
else{
if(*it==s.back())
continue; //如果l要入的等于s的末尾,则不入s
else
s.push_back(*it); 否则入s
}
}
/*或者可以直接使用list的unique函数(删除所有和前一个元素相同的元素)
l.unique();
最后再遍历l
*/
list<int>::iterator i;
for(i=s.begin();i!=s.end();i++) //遍历S
cout<<*i<<" ";
cout<<endl;
}
return 0;
}
问题 F: 不要问 问就打包
题目描述
鹏鹏爱吃水果,所以他经常去水果店打包水果回家。但是鹏鹏的买水果方式和别人不一样,他每次都会把所有的水果套餐全部买一遍,但是水果套餐里面有重复的水果。作为一个完美主义者,鹏鹏不喜欢把同一样水果吃两遍。鹏鹏说你要是能帮助他找到他点的所有水果套餐中的不重复不漏掉的水果,多出来的水果就归你所有。你能帮助鹏鹏吗。
输入
输入多组数据
第一行一个数字N,代表鹏鹏点的所有水果套餐中所有水果的数量。 1 < N < 10000 。
第二行有N个字符串代表鹏鹏点的N份水果的名字。 保证每个字符串长度不超过20。
输出
输出一个数代表鹏鹏能打包带走的不重复的不漏掉的水果数量。
样例输入
5
apple lemon apple lemon apple
3
grape mangosteen durian
样例输出
2
3
和上一题思想一致
#include <iostream>
#include<cstring>
#include<list>
using namespace std;
int main() {
int n;
string x;
while(cin>>n){
list<string> l;
list<string> s;
while(n--){
cin>>x;
l.push_back(x);
}
l.sort();
list<string>::iterator it;
for(it=l.begin();it!=l.end();it++){
if(s.empty())
s.push_back(*it);
else{
if(*it==s.back())
continue;
else
s.push_back(*it);
}
}
cout<<s.size()<<endl;
}
return 0;
}
问题 G: 水果分类
题目描述
李老板很有智慧,在春天的时候去摆摊卖应季水果,例如荔枝,菠萝,桃子啥的。
但李老板是个电脑白痴,他用收银机总是找不到客人买的水果。
所以要求你帮他进行水果分类。
给你 N 种水果,每个水果都有一个名字和一个类别,都是字符串且长度不超过 20。
输入
输入只有一组。
第一行是 n。 (1 ≤ n ≤ 100)
接下来 n 行。
每行输出两个字符串,以空格相隔,分别表示 名字 和 类别。
(1 ≤ |all_string| ≤ 20)
输出
输出参照样例。
类别 和 名字 均按照字典序排序输出。
格式为 三个空格 + “|—” + 一个空格 + 字符串。
样例输入
7
apple red
pineapple yellow
banana yellow
leechee red
peach yellow
watermelon yellow
yangtao green
样例输出
green
|— yangtao
red
|— apple
|— leechee
yellow
|— banana
|— peach
|— pineapple
|— watermelon
#include<cstdio>
#include<map>
#include<set> //set自动排序
#include<iostream>
using namespace std;
string name,color;
int main(){
int n;
cin>>n;
map<string,set<string> > mp; //定义一个map
while(n--){
cin>>name>>color;
mp[color].insert(name); //关键字为color 插入到set里
}
map<string,set<string> > ::iterator m; //定义一个map的迭代器
for(m=mp.begin();m!=mp.end();m++){
cout<<m->first<<endl; //输出color
set<string>::iterator s; //再遍历set
for(s=(m->second).begin();s!=(m->second).end();s++){
cout<<" |--- "<<*s<<endl;
}
}
return 0;
}
问题 H: 消息队列
题目描述
我们都知道,计算机储存消息是按照优先级输出的。
我们定义以下规则:
1. 每个消息,都有两个属性,分别是数据和优先级。
2. 存在一个空间,可以储存已有的消息。
3. 当遇到一个 “PUSH” 指令,后面会跟着 一个数据(字符串), 和一个优先级(整数,越大越优先)。
4. 当遇到一个 “POP” 指令,若空间中有信息,则输出该信息的数据,否则输出"NULL!"。
5. 如果两个消息,优先级一样,则越早输入的数据越优先。
详情参照样例。
输入
输入只有一组测试数据,行数未知,保证不超过 50000 行。
每一行一个命令。
- “PUSH Str N” 表示需要向空间添加进一个 优先级为 N, 数据为 Str 的消息,不需要输出。
- “POP” 表示需要输出空间中的一条消息的数据,若为空则输出"NULL!"。
(0 < |Str| < 101, 0 < N < 1001)
输出
按照每一条指令的要求输出。
PUSH 指令不需要有任何输出
样例输入
POP
PUSH First 2
POP
PUSH Second 2
PUSH THIRD 100
PUSH FOURTH 2
POP
POP
POP
POP
PUSH asddf 103
POP
样例输出
NULL!
First
THIRD
Second
FOURTH
NULL!
asddf
#include <vector>
#include <iostream>
#include<cstring>
#include<list>
#include<queue>
using namespace std;
struct node{
string str;
int vip;
}temp;
bool operator < (node a,node b){ //重载运算符
if(a.vip<b.vip)
return true; //a的优先级比b的优先级低 b优先
else
return false; //否则a优先
}
int main() {
string op,str;
int vip;
priority_queue<node> q; //定义一个结构体node的优先队列 优先级判定重载运算符
while(cin>>op){ //输入指令
if(op=="PUSH"){ //为push
cin>>str>>vip;
temp.str=str;
temp.vip=vip;
q.push(temp); //入队列
}
else{ //为pop
if(q.empty()){ //如果为空则输出空
cout<<"NULL!"<<endl;
}
else{
cout<<q.top().str<<endl; //否则输出队头
q.pop(); //并且出队列
}
}
}
return 0;
}