您的位置:首页 > 其它

STL训练(12.10.15~12.13.15)

2015-12-10 20:40 246 查看
URL: 栈和队列练习题 - Virtual Judge

PW: buctjx

DATE: 12.11.2015

A

水!中位数!

//#define LOCAL
#include <stdio.h>
#include <algorithm>
int num[10000];
int main(void)
{
#ifdef LOCAL
freopen("input.txt","r",stdin);
#endif
int N;scanf("%d",&N);
for(int i=0;i<N;++i)scanf("%d",&num[i]);
std::sort(num,num+N);
printf("%d\n",num[(N-1)/2]);
return 0;
}


B

map的key用C的char*,映射的是指针而不是字符串。

解决这个问题需要重载操作符(百度到的╮( ̄▽ ̄”)╭)

struct ptrCmp
{
bool operator()( const char * s1, const char * s2 ) const
{
return strcmp( s1, s2 ) < 0;
}
};
map<char *, int, ptrCmp> mapStr;


第一次提交我用了C++的string和cout,A TLE GET!

之后改成了int到int的映射,把电话存为一个整数,就不会超时了。

然后有两个小坑就是,输出用%03d-%04d加上前导零,没符合条件的输出No duplicates.

//#define LOCAL
#include <stdio.h>
#include <ctype.h>
#include <map>
using namespace std;
const int utoi[30]={2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,0,7,7,8,8,8,9,9,9,0};//'A'==65
int main(void)
{
#ifdef LOCAL
freopen("input.txt","r",stdin);
#endif
int N;scanf("%d",&N);getchar();//吃'\n'
map<int,int> mp;
while(N--){
int k=1000000,num=0;
char ch;
while((ch=getchar())!='\n' && ~ch){
if(ch=='-' || k==0)continue;
if(isdigit(ch))
num += k*(ch-'0');
else num += k*utoi[ch-'A'];
k /= 10;
}
if(mp.count(num))++mp[num];
else mp[num]=1;
// printf("%d\n",num);
}
int cnt=0;
for(map<int,int>::iterator it=mp.begin();it!=mp.end();++it)
if(it->second > 1){
printf("%03d-%04d %d\n",it->first/10000,it->first%10000,it->second);
++cnt;
}
if(cnt==0)printf("No duplicates.\n");
return 0;
}


C (POJ 3785)

水!

next_permutation函数:如果存在传入数组之后的排列,返回true,否则返回false,执行后,数组变为它的下一个排列。可以传入第三个比较函数

prev_permutation函数则为上一个排列。

//#define LOCAL
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int main(void)
{
#ifdef LOCAL
freopen("input.txt","r",stdin);
#endif
int T;scanf("%d",&T);
while(T--){
int N;scanf("%d",&N);
char str[85];scanf("%s",str);
if(next_permutation(str,str+strlen(str)))
printf("%d %s\n",N,str);
else printf("%d BIGGEST\n",N);
}
return 0;
}


D

检测输入的是字典还是查询,需要绕个弯子,检测getchar得到的是空格还是`\n’就好了。

用C字符串处理耗时1.1s,估计C++的流入加string会超时。

做了char*到char*的映射,C字符串的比较需要strcmp,所以重载操作符(这里还不是太明白)

(而且这样map.count()好像有问题不能用,所以用了map.find(char*))

而且map存储的是char*,指针,所以要把每个字符串存起来,使其有特异的指针。也算一种空间换时间?(雾QAQ

//#define LOCAL
#include <stdio.h>
#include <string.h>
#include <map>
using namespace std;
struct ptrCmp{
bool operator () (const char* str1,const char* str2) {
return strcmp(str1,str2)<0;
}
};
char eng[100005][11],frn[100005][11];
int main(void)
{
#ifdef LOCAL
freopen("input.txt","r",stdin);
#endif
map<char*,char*,ptrCmp> dic;
int i=0;
while(1){
char ch;
scanf("%s",eng[i]);
ch=getchar();
if(ch=='\n')break;
scanf("%s",frn[i]);
dic[frn[i]]=eng[i];
++i;
}
// for(map<char*,char*,ptrCmp>::iterator it=dic.begin();it!=dic.end();++it)
//  printf("dic[%s]=%s\n",it->first,it->second);
printf("%s\n",dic[eng[i]]);//输出以上循环多读的字符串
char str[11];
while(~scanf("%s",str)){
if(dic.find(str)!=dic.end())printf("%s\n",dic[str]);
else printf("eh\n");
}
return 0;
}


E

名字带空格,用gets读。没什么难度

//#define LOCAL
#include <stdio.h>
#include <string.h>
#include <map>
using namespace std;
struct NODE{
char party[85];
int vote;
NODE(int vote=0):vote(vote){}
};
struct ptrCmp{
bool operator () (const char* str1,const char* str2) {
return strcmp(str1,str2)<0;
}
};
int main(void)
{
#ifdef LOCAL
freopen("input.txt","r",stdin);
#endif
char name[20][85];
NODE cddt[20];
map<char*,NODE,ptrCmp> mp;

int N;scanf("%d",&N);getchar();//吃'\n'
for(int i=0;i<N;++i){
gets(name[i]);
gets(cddt[i].party);
mp[name[i]]=cddt[i];
}

char str[85];
int M;scanf("%d",&M);getchar();//吃'\n'
while(M--){
gets(str);
if(mp.find(str)!=mp.end())
++mp[str].vote;
}

// for(map<char*,NODE>::iterator it=mp.begin();it!=mp.end();++it){
//  printf("*%s* : *%s* , %d\n",it->first,it->second.party,it->second.vote);
// }
// printf("\n");

map<char*,NODE>::iterator it,fst=mp.begin(),scd=mp.begin();
for(it=mp.begin(),++it;it!=mp.end();++it){
if(it->second.vote >= fst->second.vote){
scd=fst;
fst=it;
}
}
if(fst!=scd && fst->second.vote==scd->second.vote)printf("tie\n");
else printf("%s\n",fst->second.party);
return 0;
}


F

水水水,set只有一个key,对于迭代器用*it取值就行了。

//#define LOCAL
#include <stdio.h>
#include <set>
using namespace std;
int main(void)
{
#ifdef LOCAL
freopen("input.txt","r",stdin);
#endif
int N,M;
while(~scanf("%d",&N)){
scanf("%d",&M);
set<int> st;
for(int i=N+M,in_int;i!=0;--i){
scanf("%d",&in_int);
st.insert(in_int);
}
set<int>::iterator it=st.begin();
printf("%d",*it);
for(++it;it!=st.end();++it){
printf(" %d",*it);
}
putchar('\n');
}
}


G

继续水水水,用了C++的string,真特么方便(╯‵□′)╯︵┻━┻

//#define LOCAL
#include <stdio.h>
#include <iostream>
#include <string>
#include <map>
using namespace std;
int main(void)
{
#ifdef LOCAL
freopen("input.txt","r",stdin);
#endif
int N;
while(~scanf("%d",&N) && N){
map<string,int> mp;
while(N--){
string str;
cin >> str;
if(mp.count(str))++mp[str];
else mp[str]=0;
}
map<string,int>::iterator it,max;
for(it=max=mp.begin();it!=mp.end();++it){
if(it->second > max->second)max=it;
}
cout << max->first << endl;
}
return 0;
}


H

定义结构体,保存每个病人的入队编号,优先级。

重载小于号,“先根据优先级判断,再根据入队编号判断”,优先队列就可以对该结构体排序了。

//#define LOCAL
#include <stdio.h>
#include <queue>
using namespace std;
struct NODE{
int num;
int pro;
NODE(int num=0,int pro=0):num(num),pro(pro){}
bool operator < (const NODE &P) const {
return pro==P.pro ? (num>P.num) : pro<P.pro;
}
};
int main(void)
{
#ifdef LOCAL
freopen("input.txt","r",stdin);
#endif
int N;
NODE ptt[2000];
while(~scanf("%d",&N)){
int cnt=1;
priority_queue<NODE> doc[4];
while(N--){
char str[10];
int A,B;
scanf("%s",str);
if(str[0]=='I'){
scanf("%d%d",&A,&B);
ptt[cnt].num=cnt;
ptt[cnt].pro=B;
doc[A].push(ptt[cnt++]);
}else {
scanf("%d",&A);
if(doc[A].empty())printf("EMPTY\n");
else {
printf("%d\n",doc[A].top().num);
doc[A].pop();
}
}
}
}
return 0;
}


I

思路,将所有输入读入string并放进集合,把每个单词拆成各个长度的两段string,分别检测是否两段都在集合中,若都在,则输出。

//#define LOCAL
#include <stdio.h>
#include <iostream>
#include <string>
#include <set>
using namespace std;
int main(void)
{
#ifdef LOCAL
freopen("input.txt","r",stdin);
#endif
string str;
set<string> st;
while(cin>>str)st.insert(str);
for(set<string>::iterator it=st.begin();it!=st.end();++it){
int len=(*it).length();
for(int i=1;i<len;++i){
// cout<<(*it).substr(0,i)<<' '<<(*it).substr(i,len-i)<< '#' <<endl;
if(st.count((*it).substr(0,i)) && st.count((*it).substr(i,len-i))){
cout << *it <<endl;
break;
}
}
}
return 0;
}


J

结构体排序,重载小于号,优先排D,次排C。

第一组D的最小值符合条件;

对于其余每组D,找出最小值C2,若C2小于“上一组D的最小值C1”,那么这个C2符合条件。

换个说法就是:

在D-C坐标系中,一点M符合条件等价于“M左下方(包括等于)不存在其他元素”。

//#define LOCAL
#include <stdio.h>
#include <algorithm>
struct NODE{
bool exist;
int D,C;
NODE(bool exist=true,int D=0,int C=0):exist(exist),D(D),C(C){}
bool operator < (const NODE &N) const{
return D==N.D ? (C<N.C) : D<N.D;
}
};
int main(void)
{
#ifdef LOCAL
freopen("input.txt","r",stdin);
#endif
int N;
while(~scanf("%d",&N) && N){
NODE hotel[10000];
for(int i=0;i<N;++i)
scanf("%d%d",&hotel[i].D,&hotel[i].C);
std::sort(hotel,hotel+N);
int cnt=1,min_C=hotel[0].C;
for(int i=1;i<N;++i){
if(hotel[i].C < min_C){
min_C=hotel[i].C;
++cnt;
}
}
printf("%d\n",cnt);
}
return 0;
}


都是熟悉STL数据容器的题,这次还是很简单的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: