• 紫书第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("!
    ")
    #define INF 10000
    #define MAXN 5010
    #define MAX(a,b) a>b?a:b
    #define blank pf("
    ")
    #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:
    ",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
    ",x);
                        continue;
                   }
                   else
                        pf("%d found at %d
    ",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("!
    ")
    #define INF 10000
    #define MAXN 5010
    #define MAX(a,b) a>b?a:b
    #define blank pf("
    ")
    #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("!
    ")
    #define INF 10000
    #define MAXN 5010
    #define MAX(a,b) a>b?a:b
    #define blank pf("
    ")
    #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("!
    ")
    #define INF 10000
    #define MAXN 5010
    #define MAX(a,b) a>b?a:b
    #define blank pf("
    ")
    #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("!
    ")
    #define INF 10000
    #define MAXN 5010
    #define MAX(a,b) a>b?a:b
    #define blank pf("
    ")
    #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("!
    ")
    #define INF 10000
    #define MAXN 5010
    #define MAX(a,b) a>b?a:b
    #define blank pf("
    ")
    #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
    ",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
    ",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("!
    ")
    #define INF 10000
    #define MAXN 5010
    #define MAX(a,b) a>b?a:b
    #define blank pf("
    ")
    #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.
    ",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("!
    ")
    #define INF 10000
    #define MAXN 5010
    #define MAX(a,b) a>b?a:b
    #define blank pf("
    ")
    #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每个字符读取,遇到,或 就处理

    处理字符可以用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("!
    ")
    #define INF 10000
    #define MAXN 5010
    #define MAX(a,b) a>b?a:b
    #define blank pf("
    ")
    #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
    ",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=='
    ' || ch == '
    ')
                   {
                        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
    ");
                             pf("%d %d
    %d %d
    ",data[p]+1,r+1,c1+1,c2+1);
                             return;
                        }
                        else
                             data[p]= r;
                   }
              }
         }
         pf("YES
    ");
    }
    
    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("!
    ")
    #define INF 10000
    #define MAXN 5010
    #define MAX(a,b) a>b?a:b
    #define blank pf("
    ")
    #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 +"
    ";
              }
    
              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
    ");
                   cout<<"     MAIL FROM:<"<<s<<">
    ";
                   pf("     250
    ");
                   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
    ");
                        }
                        else
                             pf("     550
    ");
                   }
                   if(ok)
                   {
                        cout<<"     DATA
         354
    "<<data;
                        pf("     .
         250
    ");
                   }
                   pf("     QUIT
         221
    ");
              }
         }
    }

    例题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("!
    ")
    #define INF 10000
    #define MAXN 5010
    #define MAX(a,b) a>b?a:b
    #define blank pf("
    ")
    #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:
    %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;
    
    
         }
    }
  • 相关阅读:
    poj2478
    poj2376
    poj2192
    poj1062
    [HDOJ2639]Bone Collector II(第k优01背包)
    [HDOJ3466]Proud Merchants(贪心+01背包)
    [HDOJ5510]Bazinga(并查集)
    [POJ3264]Balanced Lineup(线段树,区间最值差)
    [HDOJ4325]Flowers(树状数组 离散化)
    [HDOJ5521]Meeting(最短路)
  • 原文地址:https://www.cnblogs.com/qlky/p/5174047.html
Copyright © 2020-2023  润新知