紫书第5章 C++STL

例题

 

例题5-1 大理石在哪儿(Where is the Marble?,Uva 10474)

主要是熟悉一下sort和lower_bound的用法

关于lower_bound:

http://blog.csdn.net/niushuai666/article/details/6734403

此外还有upper_bound

http://blog.csdn.net/niushuai666/article/details/6734650

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
#include <cctype>
using namespace std;

#define mem(a,b) memset(a,b,sizeof(a))
#define pf printf
#define sf scanf
#define spf sprintf
#define debug printf("!\n")
#define INF 10000
#define MAXN 5010
#define MAX(a,b) a>b?a:b
#define blank pf("\n")
#define LL long long

int a[10005];

int main()
{
     int n,q,i,x,cnt=1;
     while(~sf("%d%d",&n,&q) && n)
     {
          pf("CASE# %d:\n",cnt++);
          for(i=0;i<n;i++) sf("%d",&a[i]);
          sort(a,a+n);
          while(q--)
          {
               sf("%d",&x);
               int p = lower_bound(a,a+n,x)-a;
               if(a[p]!=x)
               {
                    pf("%d not found\n",x);
                    continue;
               }
               else
                    pf("%d found at %d\n",x,p+1);
          }
     }
}

 

例题5-2 木块问题(The Blocks Problem,Uva 101)

主要是熟悉vector的pb和resize,以及字符串结束的处理方法

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
#include <cctype>
#include <vector>
using namespace std;

#define mem(a,b) memset(a,b,sizeof(a))
#define pf printf
#define sf scanf
#define spf sprintf
#define pb push_back
#define debug printf("!\n")
#define INF 10000
#define MAXN 5010
#define MAX(a,b) a>b?a:b
#define blank pf("\n")
#define LL long long

vector<int> pile[30];
int n;

void find_block(int x,int &p,int &h)
{
     for(p=0;p<n;p++)
     {
          for(h=0;h<pile[p].size();h++)
          {
               if(pile[p][h] == x) return;
          }
     }
}

void clear_block(int p,int h)
{
     int i;
     for(i = h+1;i<pile[p].size();i++)
     {
          int b = pile[p][i];
          pile[b].pb(b);
     }
     pile[p].resize(h+1);
}

void onto_block(int p,int h,int p2)
{
     int i;
     for(i = h;i<pile[p].size();i++)
          pile[p2].pb(pile[p][i]);
     pile[p].resize(h);
}

void print()
{
     int p,h;
     for(p=0;p<n;p++)
     {
          pf("%d:",p);
          for(h=0;h<pile[p].size();h++)
          {
               pf(" %d",pile[p][h]);
          }
          blank;
     }
}

int main()
{
     int i,a,b;
     sf("%d",&n);
     for(i=0;i<n;i++) pile[i].pb(i);
     char s[5],s1[5];

     while(sf("%s",s) && s[0]!='q')
     {

          sf("%d%s%d",&a,s1,&b);
          int pa,pb,ha,hb;
          find_block(a,pa,ha);
          find_block(b,pb,hb);
          if(pa==pb) continue;
          if(!strcmp(s,"move")) clear_block(pa,ha);
          if(!strcmp(s1,"onto")) clear_block(pb,hb);
          onto_block(pa,ha,pb);
     }
     print();
}

 

例题5-3 安迪的第一个字典(Andy's First Dictionary,Uva 10815)

主要是熟悉set的insert还有iterator

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
#include <cctype>
#include <vector>
#include <set>
#include <sstream>
using namespace std;

#define mem(a,b) memset(a,b,sizeof(a))
#define pf printf
#define sf scanf
#define spf sprintf
#define pb push_back
#define debug printf("!\n")
#define INF 10000
#define MAXN 5010
#define MAX(a,b) a>b?a:b
#define blank pf("\n")
#define LL long long

set<string> dict;

int main()
{
     string s,buf;
     while(cin>>s)
     {
          int i;
          for(i=0;i<s.length();i++)
          {
               if(isalpha(s[i])) s[i] = tolower(s[i]);
               else s[i] = ' ';
          }
          stringstream ss(s);
          while(ss>>buf) dict.insert(buf);
     }
     for(set<string>::iterator it = dict.begin();it!=dict.end();++it)
          cout<<*it<<endl;
}

 

例题5-4 反片语(Ananagrams,Uva 156)

主要是熟悉map的用法。

给string和vector<string>排序可以用sort(str.begin(),str.end());即字典序

map<string,int> mp可以直接用mp[string] = int;在这道题可以表示某个字符串出现的次数

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
#include <cctype>
#include <vector>
#include <set>
#include <map>
#include <sstream>
using namespace std;

#define mem(a,b) memset(a,b,sizeof(a))
#define pf printf
#define sf scanf
#define spf sprintf
#define pb push_back
#define debug printf("!\n")
#define INF 10000
#define MAXN 5010
#define MAX(a,b) a>b?a:b
#define blank pf("\n")
#define LL long long

map<string,int> cnt;
vector<string> words;

string repr(const string &s)
{
     string ans = s;
     for(int i=0;i<ans.length();i++)
     {
          ans[i] = tolower(ans[i]);
     }
     sort(ans.begin(),ans.end());
     return ans;
}

int main()
{
     string s;
     while(cin>>s)
     {
          if(s[0]=='#') break;
          words.pb(s);
          string r = repr(s);
          if(!cnt.count(r)) cnt[r] = 0;
          cnt[r]++;
     }
     vector<string> ans;
     for(int i = 0;i<words.size();i++)
     {
          if(cnt[repr(words[i])]==1) ans.pb(words[i]);
     }
     sort(ans.begin(),ans.end());
     for(int i = 0;i<ans.size();i++)
     {
          cout<<ans[i]<<endl;
     }

}

 

例题5-5 集合栈计算机(The Set Stack Computer,ACM/ICPC NWERC2006,UVa12096)

 map映射+vector,inserter插入迭代器的使用,set_union和set_intersection

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
#include <cctype>
#include <vector>
#include <iterator>
#include <set>
#include <map>
#include <sstream>
using namespace std;

#define mem(a,b) memset(a,b,sizeof(a))
#define pf printf
#define sf scanf
#define spf sprintf
#define pb push_back
#define debug printf("!\n")
#define INF 10000
#define MAXN 5010
#define MAX(a,b) a>b?a:b
#define blank pf("\n")
#define LL long long
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())

typedef set<int> Set;
map<Set,int> IDcache;
vector<Set> Setcache;

int ID(Set x)
{
     if(IDcache.count(x)) return IDcache[x];
     Setcache.pb(x);
     return IDcache[x] = Setcache.size() - 1;
}

int main()
{
     stack<int> s;
     int t;
     cin>>t;
     while(t--)
     {
          int n;
          cin>>n;
          while(n--)
          {
               string op;
               cin>>op;
               if(op[0]=='P') s.push(ID(Set()));
               else if(op[0]=='D') s.push(s.top());
               else
               {
                    Set x1 = Setcache[s.top()];s.pop();
                    Set x2 = Setcache[s.top()];s.pop();
                    Set x;
                    if(op[0]=='A')
                    {
                         x = x2;
                         x.insert(ID(x1));
                    }
                    if(op[0]=='U') set_union(ALL(x1),ALL(x2),INS(x));
                    if(op[0]=='I') set_intersection(ALL(x1),ALL(x2),INS(x));
                    s.push(ID(x));
               }
               cout<<Setcache[s.top()].size()<<endl;
          }
          cout<<"***"<<endl;
     }

}

 

例题5-6 团体队列(Team Queue,UVa540)

队列的使用

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <cctype>
#include <vector>
#include <iterator>
#include <set>
#include <map>
#include <sstream>
using namespace std;

#define mem(a,b) memset(a,b,sizeof(a))
#define pf printf
#define sf scanf
#define spf sprintf
#define pb push_back
#define debug printf("!\n")
#define INF 10000
#define MAXN 5010
#define MAX(a,b) a>b?a:b
#define blank pf("\n")
#define LL long long
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())

int main()
{
     int t,x,i,kase=1;
     while(sf("%d",&t),t)
     {
          pf("Scenario #%d\n",kase++);
          map<int,int> team;
          for(i=0;i<t;i++)
          {
               int n;
               sf("%d",&n);
               while(n--)
               {
                    sf("%d",&x);
                    team[x] = i;
               }
          }
          queue<int> q,q2[1010];
          string op;
          while(cin>>op && op[0]!='S')
          {
               if(op[0] == 'E')
               {
                    int r;
                    sf("%d",&r);
                    int y = team[r];
                    if(q2[y].empty()) q.push(y);
                    q2[y].push(r);
               }
               if(op[0] == 'D')
               {
                    int y = q.front();
                    pf("%d\n",q2[y].front());
                    q2[y].pop();
                    if(q2[y].empty())
                         q.pop();
               }
          }
          blank;
     }
}

 

例题5-7 丑数(Ugly Numbers,Uva 136)

优先队列的应用

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <cctype>
#include <vector>
#include <iterator>
#include <set>
#include <map>
#include <sstream>
using namespace std;

#define mem(a,b) memset(a,b,sizeof(a))
#define pf printf
#define sf scanf
#define spf sprintf
#define pb push_back
#define debug printf("!\n")
#define INF 10000
#define MAXN 5010
#define MAX(a,b) a>b?a:b
#define blank pf("\n")
#define LL long long
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define pqueue priority_queue

int con[]={2,3,5};

int main()
{
     int i,j;
     set<LL> s;
     pqueue<LL,vector<LL>,greater<LL> >pq;
     s.insert(1);
     pq.push(1);
     for(i=1;;i++)
     {
          LL t = pq.top();pq.pop();
          if(i==1500)
          {
               pf("The 1500'th ugly number is %I64d.\n",t);
               break;
          }
          for(j=0;j<3;j++)
          {
               LL x = t*con[j];
               if(!s.count(x))
               {
                    s.insert(x);
                    pq.push(x);
               }
          }
     }
}

 

例题5-8 Unixls命令(Unix ls,UVa400)

对于这样控制格式的要求(比如对齐)可以用规定长度然后填充的方式输出

col求出来后,row应该是(n-1)/col+1而不是n/col

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <cctype>
#include <vector>
#include <iterator>
#include <set>
#include <map>
#include <sstream>
using namespace std;

#define mem(a,b) memset(a,b,sizeof(a))
#define pf printf
#define sf scanf
#define spf sprintf
#define pb push_back
#define debug printf("!\n")
#define INF 10000
#define MAXN 5010
#define MAX(a,b) a>b?a:b
#define blank pf("\n")
#define LL long long
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define pqueue priority_queue

const int maxcol = 60;
string filenames[105];

void print(const string& s,int len,char extra)
{
     cout<<s;
     for(int i = 0;i<len-s.length();i++)
          cout<<extra;
}

int main()
{
     int n,i,j;
     while(~sf("%d",&n))
     {
          int ma = 0;
          for(i=0;i<n;i++)
          {
               cin>>filenames[i];
               ma = max(ma,(int)filenames[i].length());
          }
          int col = (maxcol-ma)/(ma+2) + 1;
          int row = (n-1)/col +1;
          print("",60,'-');
          blank;
          sort(filenames,filenames+n);
          for(i = 0;i<row;i++)
          {
               for(j=0;j<col;j++)
               {
                    int idx = j*row + i;
                    if(idx<n) print(filenames[idx],j==col-1?ma:ma+2,' ');
               }
               blank;
          }
     }
}

 

例题5-9 数据库(Database,ACM/ICPC NEERC 2009,UVa1592)

这题的思路是:

因为字符串比较的话比较慢,所以可以先做一个预处理,将所有字符串用一个ID表示

读取字符是这样的:因为字符用,和回车分隔,所以可以用getchar每个字符读取,遇到,或\n就处理

处理字符可以用map映射,如果count==0就pb到ID集vector里

然后就是遍历。先用一个结构保存两个ID。三重循环遍历,如果相同的话则输出

struct里小于号的定义很不错,return x<r.x || x==r.x && y<r.y;先看第一个的大小,相等再看第二个

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <cctype>
#include <vector>
#include <iterator>
#include <set>
#include <map>
#include <sstream>
using namespace std;

#define mem(a,b) memset(a,b,sizeof(a))
#define pf printf
#define sf scanf
#define spf sprintf
#define pb push_back
#define debug printf("!\n")
#define INF 10000
#define MAXN 5010
#define MAX(a,b) a>b?a:b
#define blank pf("\n")
#define LL long long
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define pqueue priority_queue

const int ROW = 10000+10;
const int COL = 10+5;

int m,n;

struct node
{
     int x,y;
     node(int xx,int yy):x(xx),y(yy){}
     bool operator <(const node& r) const { return x<r.x || x==r.x && y<r.y;}
};

map<string,int> IDcache;
vector<string> stringSet;
vector<int> Text[ROW];
map<node,int> data;


int ID(string str)
{
     //cout<<"str: "<<str<<endl;
     if(IDcache.count(str)) return IDcache[str];
     stringSet.pb(str);
     //pf("id: %d\n",stringSet.size()-1);
     return IDcache[str] = stringSet.size()-1;
}

void read()
{
     string str;
     int i,j;
     char ch = getchar();
     for(i=0;i<n;i++)
     {
          for(;;)
          {
               ch = getchar();
               if(ch=='\r' || ch == '\n')
               {
                    if(!str.empty()) Text[i].pb(ID(str));
                    str.clear();
                    break;
               }
               if(ch!=',') str+=ch;
               else
               {
                    Text[i].pb(ID(str));str.clear();
               }
          }
//          cout<<"i "<<i<<endl;
//          for(j=0;j<Text[i].size();j++)
//               cout<<"j "<<j<<" Text: "<<Text[i][j]<<endl;
     }

}

void sol()
{
     int c1,c2,r,i,j,k;
     for(c1=0;c1<m;c1++)
     {
          for(c2=c1+1;c2<m;c2++)
          {
               data.clear();
               for(r=0;r<n;r++)
               {
                    int x = Text[r][c1];
                    int y = Text[r][c2];
                    node p(x,y);
                    if(data.count(p))
                    {
                         pf("NO\n");
                         pf("%d %d\n%d %d\n",data[p]+1,r+1,c1+1,c2+1);
                         return;
                    }
                    else
                         data[p]= r;
               }
          }
     }
     pf("YES\n");
}

int main()
{
     int i,j;
     while(~sf("%d%d",&n,&m))
     {
          read();
          sol();
          for(i=0;i<n;i++) Text[i].clear();
          IDcache.clear();
          stringSet.clear();
     }
}

 

例题5-10 PGA巡回赛的奖金(PGA Tour Prize Money,ACM/ICPC World Finals1990,UVa207)

 

例题5-11 邮件传输代理的交互(The Letter Carrier's Rounds, ACM/ICPC World Finals 1999, UVa814)

 

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <cctype>
#include <vector>
#include <iterator>
#include <set>
#include <map>
#include <sstream>
using namespace std;

#define mem(a,b) memset(a,b,sizeof(a))
#define pf printf
#define sf scanf
#define spf sprintf
#define pb push_back
#define debug printf("!\n")
#define INF 10000
#define MAXN 5010
#define MAX(a,b) a>b?a:b
#define blank pf("\n")
#define LL long long
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define pqueue priority_queue

set<string> addr;

void getn(string &s,string &user,string &mta)
{
     int k = s.find('@');
     user = s.substr(0,k);
     mta = s.substr(k+1);
}

int main()
{
     string s,mta,user,ma,na,user1,mta1,t;
     int n;
     while(cin>>s && s[0]!='*')
     {
          cin>>ma>>n;
          while(n--)
          {
               cin>>na;
               addr.insert(na+"@"+ma);
          }
     }

     while(cin>>s && s!="*")
     {
          getn(s,user,mta);

          vector<string> MTA;
          map<string,vector<string> > dest;//用户
          set<string> vis;
          while(cin>>t && t!="*")
          {
               getn(t,user1,mta1);
               if(vis.count(t)) continue;
               vis.insert(t);
               if(!dest.count(mta1))
               {
                    MTA.pb(mta1);
                    dest[mta1] = vector<string>();
               }
               dest[mta1].pb(t);
          }
          string data;
          getline(cin,t);

          while(getline(cin,t) && t[0]!='*')
          {
               data+="     " + t +"\n";
          }

          for(int i = 0;i<MTA.size();i++)
          {
               string mta2 = MTA[i];
               vector<string> users = dest[mta2];
               cout<<"Connection between "<<mta<<" and "<<mta2<<endl;
               cout<<"     HELO "<<mta<<endl;
               pf("     250\n");
               cout<<"     MAIL FROM:<"<<s<<">\n";
               pf("     250\n");
               bool ok = false;
               for(int j = 0;j<users.size();j++)
               {
                    cout<<"     RCPT TO:<"<<users[j]<<">"<<endl;
                    if(addr.count(users[j]))
                    {
                         ok = true;
                         pf("     250\n");
                    }
                    else
                         pf("     550\n");
               }
               if(ok)
               {
                    cout<<"     DATA\n     354\n"<<data;
                    pf("     .\n     250\n");
               }
               pf("     QUIT\n     221\n");
          }
     }
}

 

例题5-12 城市正视图(Urban Elevations, ACM/ICPC World Finals 1992, UVa221)

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <cctype>
#include <vector>
#include <iterator>
#include <set>
#include <map>
#include <sstream>
using namespace std;

#define mem(a,b) memset(a,b,sizeof(a))
#define pf printf
#define sf scanf
#define spf sprintf
#define pb push_back
#define debug printf("!\n")
#define INF 10000
#define MAXN 5010
#define MAX(a,b) a>b?a:b
#define blank pf("\n")
#define LL long long
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define pqueue priority_queue

int n;
double s[105*2];

struct building
{
     int id;
     double x,y,w,h,d;
     bool operator <(const building& a) const
     {
          return x<a.x || (x==a.x && y<a.y);
     }
     //一定要是小于号,不然会报错
}b[105];

bool cover(int i,double mx)
{
     return b[i].x<=mx && b[i].x+b[i].w>=mx;
}

bool visible(int i,double mx)
{
     if(!cover(i,mx)) return false;
     for(int k = 0;k<n;k++)
     {
          if(cover(k,mx) && b[k].y<b[i].y && b[k].h>=b[i].h)
               return false;
     }
     return true;
}

int main()
{
     int kase = 0;
     while(sf("%d",&n)==1 && n)
     {
          for(int i = 0;i<n;i++)
          {
               sf("%lf%lf%lf%lf%lf",&b[i].x,&b[i].y,&b[i].w,&b[i].d,&b[i].h);
               s[i*2]=b[i].x;
               s[i*2+1]=b[i].x+b[i].w;
               b[i].id=i+1;
          }
          sort(b,b+n);
          sort(s,s+n*2);
          int m = unique(s,s+n*2)-s;

          if(kase++) blank;
          pf("For map #%d, the visible buildings are numbered as follows:\n%d",kase,b[0].id);

          for(int i=1;i<n;i++)
          {
               bool vis = false;
               for(int j = 0;j<m-1;j++)
                    if(visible(i,(s[j]+s[j+1])/2)){vis=true;break;}
               if(vis){pf(" %d",b[i].id);};
          }
          blank;


     }
}

 

转载于:https://www.cnblogs.com/qlky/p/5174047.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值