紫薯 第五章 STL習題(1-9)

Alignment of Code UVA - 1593sstream

在這裏插入圖片描述

題意:

把文本格式化。

思路:

直接sstream輸入,複習了一遍

	stringstream ss(s);
	while(ss>>buf)
	{
	line[cnt].push_back(buf);
	limit[col]=max(limit[col],(int)line[cnt][col].size());
   	col++;
	}
cnt++;

反思

我還用了set,其實直接開一個limit數組,去記錄每列的最大值,即可。

AC

#include <iostream>
#include <string>
#include <sstream>
#include <set>
#include <vector>
#include <cstring>
#define For(i,x,y) for(register int i=(x); i<=(y); i++)
using namespace std;
set<int>length[1010];
vector<string>line[1010];
vector<int>limit(1010);
void print(const string &s, int len)
{
    cout<<s;
    int ed=len-s.size();
    For(i,1,ed)cout<<' ';
}
int main()
{
    string buf,s,t;
    int cnt=1,col=0;
    while(getline(cin,s))
    {
        col=0;
        stringstream ss(s);
        while(ss>>buf)
        {
            line[cnt].push_back(buf);
            limit[col]=max(limit[col],(int)line[cnt][col].size());
            col++;
        }
        cnt++;
    }
    cnt--;//
    /*
    For(i,1,cnt)
    {
        for(int j=0; j<line[i].size(); j++)
        {
            int len=line[i][j].size();
            length[j].insert(len);
        }
    }
    */
    For(i,1,cnt)
    {
        int ed=line[i].size()-1;
        for(int j=0; j<line[i].size(); j++)
        {
            if(j==ed)cout<<line[i][j];
            else //print(line[i][j],(*length[j].rbegin())+1);
                print(line[i][j],limit[j]+1);
        }
        cout<<endl;
    }
    return 0;
}
/*
  start:  integer;    // begins here
  stop:  integer; // ends␣here
  s:  string;
  c: char; // temp
*/

Ducci Sequence UVA - 1594map

在這裏插入圖片描述
在這裏插入圖片描述

題意:

對於一個n元組,可以對於每個數求出它和下一個數的差的絕對值(最後一個和第一個),得到一個新的n元組,重複這個過程得到Ducci序列,試問最終n元組會變成0,還是進入循環。

思路:

map < vector< int >,int >vis
key值爲一個數組,統計時用vis.count,看是否出現過

收穫

  1. 對於vector的resize。的原理其實和賦值差不多
    v.resize(size,value)~ vector< int >v(size,value)

  2. 在main函數裏,resize後,默認vector的值爲0.

  3. 對於map的訪問,假如使用if(ma【a】==0)如果之前沒有對ma【a】=1進行賦值操作,系統會自動賦值。有時候可能會有影響

AC

#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#define For(i,x,y) for(register int i=(x); i<=(y); i++)
using namespace std;
void solve(vector<int> &a)
{
    int temp,top=a[0],ed=a.size()-1;
    for(int i=0; i<a.size(); i++)
    {
        temp=(i==ed)?(abs(a[i]-top)):abs(a[i]-a[i+1]);
        a[i]=temp;
    }
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,x,cnt=0;
        cin>>n;
        int flag=1;
        vector<int>a,b(n);
        map<vector<int>,int>vis;
        vis[b]=cnt++;
        For(i,0,n-1)cin>>x,a.push_back(x);
        while(cnt<=1001)
        {
          //  if(vis.count(a))cout<<"ok"<<endl;
           // if(vis[a]==0)cout<<"OK"<<endl;
            if(vis.count(a))
            {
                if(vis[a]==0)flag=0;
                break;
            }
            //cout<<"cnt="<<cnt<<endl;
            vis[a]=cnt++;
            solve(a);
            //for(int i=0; i<a.size(); i++)cout<<a[i]<<' ';
           // cout<<endl;
        }
        if(flag)cout<<"LOOP"<<endl;
        else cout<<"ZERO"<<endl;
    }
    return 0;
}

Throwing cards away I UVA - 10935(隊列)

在這裏插入圖片描述

題意&&題解:

本題是去隊首,之後再把現在的隊首加到隊尾。直到只剩下一個元素爲。
簡單模擬。

反思

本題沒有考慮n=1的特判,1wa。

AC

#include <iostream>
#include <queue>
#include <vector>
#define For(i,x,y) for(register int i=(x); i<=(y); i++)
using namespace std;
queue<int>q;
int main()
{
    int n;
    while(cin>>n,n)
    {
        vector<int>discard;
        For(i,1,n)q.push(i);
        cout<<"Discarded cards:";
        while(!q.empty())
        {
            if(q.size()==1)break;
            discard.push_back(q.front());q.pop();
            q.push(q.front());q.pop();
        }
        if(discard.size()!=0)//注意特判,當n=1時,本題應該沒有丟棄卡牌。
        {
            int ed=discard.size()-1;
            for(int i=0; i<discard.size(); i++)
            {
                cout<<' '<<discard[i];
                if(i!=ed)cout<<",";
            }
        }
        cout<<endl;
        cout<<"Remaining card: "<<q.front()<<endl;q.pop();
    }
    return 0;
}

Foreign Exchange UVA - 10763map記錄二元組)

在這裏插入圖片描述
在這裏插入圖片描述

題意:

有n個學生想交換到其他學校學習。爲了簡單起見,規定每一個想從A學校轉到B學校的學生必須找到一個想從B換到A的“搭檔”。判斷交換是否可以進行。

思路:

正着跑一遍map,之後再反着跑一遍

AC

#include <iostream>
#include <map>
#define mp make_pair
#define For(i,x,y) for(register int i=(x); i<=(y); i++)
using namespace std;
const int maxn=5e5+10;
typedef pair<int,int>pa;
map<pa,int>ma;
int a[maxn],b[maxn];
int main()
{
    int n,x,y;
    while(cin>>n,n)
    {
        int flag=1;
        ma.clear();
        For(i,1,n)cin>>a[i]>>b[i],ma[mp(a[i],b[i])]++;
        For(i,1,n)
        {
            x=b[i],y=a[i];
            if(ma[mp(x,y)]==0)
            {
               flag=0;//cout<<"NO"<<endl;
                break;
            }
            else ma[mp(x,y)]--;
        }
        if(flag)cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
    return 0;
}

Compound Words UVA - 10391map

在這裏插入圖片描述

題意:

給你一個詞典,要找出所有的複合詞,即恰好有兩個單詞連接而成的單詞。按字典序輸出複合詞。

思路:

好像可以把一個單詞X2.
由於單詞很多,所以直接暴力找二元組會超時。

  1. 先可以用map記錄單詞是否出現過,
  2. 可以把一個單詞分解,每次分解後,看t1和t2是否存在於原字典。

AC

#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn=1e5+2e4+10;
string s[maxn],t1,t2;
map<string,int>ma;
vector<string>ans;
int main()
{
    int cnt=0,ed;
    while(cin>>s[++cnt])ma[s[cnt]]++;
    /*
    while(cin>>s[++cnt],cnt<=10)
    {
        ma[s[cnt]]++;
    }
    */
    for(int i=1; i<=cnt; i++)
    {
        t2=t1="";ed=s[i].size()-1;
        for(int k=0; k<s[i].size(); k++)
        {
            t1+=s[i][k];
            t2=s[i].substr(k+1);
            if(k==ed)break;
            if(ma.count(t1)&&ma.count(t2))
            {
                ans.push_back(s[i]);
                break;
            }
        }
    }
    sort(ans.begin(),ans.end());
    for(int i=0; i<ans.size(); i++)cout<<ans[i]<<endl;
    return 0;
}

Symmetry UVA - 1595map記錄二元組)

在這裏插入圖片描述
在這裏插入圖片描述

題意:

給出平面上n個點,問是否可以找到一條豎線,使得左右對稱。

思路:

  1. 輸入時記錄邊界 l 和 r 即可。
  2. 之後中點就是 l+r /2(由於是整數,所以最好不要用除法)
    x1+x2=l+r。
  3. 0n檢查即可。(可以預處理,點對的二元組)

AC

#include <iostream>
#include <map>
#include <cmath>
#define mp make_pair
#define For(i,x,y) for(register int i=(x); i<=(y); i++)
using namespace std;
const double eps=1e-8;
typedef pair<int,int>pa;
map<pa,int>ma;
int a[1010],b[1010],n,x[3000];
bool check(int mx)
{
    For(j,1,n)
    {
        if(ma.count(mp(mx-a[j],b[j])))continue;
        else return false;
    }
    return true;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        ma.clear();
        int flag=0;
        int l=1e4,r=-1e4;
        cin>>n;
        For(i,1,n)
        {
            cin>>a[i]>>b[i];
            ma[mp(a[i],b[i])]++;
            l=min(l,a[i]);
            r=max(r,a[i]);
        }
        //cout<<l<<' '<<r<<endl;
        if(check((l+r)))flag=1;
        if(flag)cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
    return 0;
}

Printer Queue UVA - 12100隊列&&優先隊列

在這裏插入圖片描述
在這裏插入圖片描述

題意:

有一臺打印機是按隊列打印,並且優先級大的先打印,每次打印1min。
問想要m被打印,需要多久。

思路:

  1. 可以用一個優先隊列 存儲 優先級,每次打印時都出隊,
  2. 之後從隊首開始找,找到符合優先級的,(模擬)
  3. 至於每個任務的優先級可以在輸入時,存起來。rk

AC

#include <iostream>
#include <queue>
#define For(i,x,y) for(register int i=(x); i<=(y); i++)
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        priority_queue<int>pq;
        queue<int>q;
        int n,m,top,cnt=0;
        int rk[101];
        cin>>n>>m;
        For(i,0,n-1)
        {
            cin>>rk[i];
            q.push(i);
            pq.push(rk[i]);
        }
        while(!q.empty())
        {
            cnt++;
            top=pq.top();pq.pop();
            while(top!=rk[q.front()])q.push(q.front());q.pop();
            if(q.front()==m)break;
            q.pop();
        }
        cout<<cnt<<endl;
    }
    return 0;
}

Borrowers UVA - 230(map&&set模擬)(WF1994)

在這裏插入圖片描述
在這裏插入圖片描述

題意:

模擬一個圖書管理系統。
首先輸入若干圖書的 標題 和 作者(標題各不相同,以END結束)。
然後時指令:borrow,return,shelve:指令表示把所有已歸還但還未上架的圖書排序後依次插入書架並輸出圖書標題和插入位置(特別的,是插入第一個位置)
圖書排序的方法是先按作者從小到大排序,再按標題從小到大排序。再處理第一條指令前,應該先將所有圖書按這種順序排序。

思路:

  1. 定義book,爲name(書名),writer(作者名),(book的自定義小於運算和題目的一樣)
  2. set< book >lib(爲圖書光), set< book >return(爲返回的書)
  3. 可以用map記錄輸入的書籍名稱name所對應的book
    map< string,book >。後面方便插入。
  4. 之後開始讀取操作。borrow借走書,就先把書從lib裏刪除。
  5. return,就先把書放在return裏。
  6. shelve就把return裏的書插入到lib裏,按順序插。

ps:本題好像說沒有引號,其實是有引號的。qwq

反思

  1. while(cin>>X&&(situation))(cinEOF和scanf一樣,同理也和getline一樣)
  2. getline的返回值是

getline

cin.getline(char*, size,終止字符)
getline(流,string,終止字符)。

AC

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <set>
#include <map>
#include <sstream>
using namespace std;
const string word1="BORROW";
const string word2="RETURN";
const string word3="SHELVE";
struct book
{
    string name;
    string wrt;
    bool operator<(const book &a)const
    {return wrt<a.wrt||(wrt==a.wrt&&name<a.name);}
} b;
set<book>lib;
set<book>rtu;
map<string,book>ma;
string s,t1,t2,t;
void init()
{
    while(getline(cin,s)&&s!="END")
    {
        int pos=s.find("by");
        t1=s.substr(0,pos-1);
        t2=s.substr(pos+3);
        //t2=t1="";
       // stringstream ss(s);
      //  while(ss>>t&&t!="by")t1+=t;
       // while(ss>>t)t2+=t;
        lib.insert({t1,t2});
        ma[t1]={t1,t2};
       // cout<<t1<<' '<<t2<<endl;
    }
}
/*
void erase_dot(const string &s)
{
    int len=s.size()-1;
    for(int i=1; i<len; i++)cout<<s[i];
}
*/
void print()
{
    set<book>::iterator it,temp;
    for(it=rtu.begin(); it!=rtu.end(); it++)
    {
        temp=lib.lower_bound(*it);
        if(temp==lib.begin())
        {
            cout<<"Put "<<(*it).name<<" first"<<endl;;
            //erase_dot( (*it).name );
            //cout<<" first"<<endl;
        }
        else
        {
            cout<<"Put "<<(*it).name<<" after "<<(*(--temp)).name<<endl;
          //  erase_dot( (*it).name );
          //  cout<<" after ";
           // erase_dot( (*(--temp)).name);
           // cout<<endl;
        }
        lib.insert(*it);
    }
    cout<<"END"<<endl;
    rtu.clear();
}
void work()
{
    while(getline(cin,s)&&s!="END")
    {
        t2=t1="";
       // stringstream ss(s);
        //ss>>t1;
        int pos=s.find(" ");
        t1=s.substr(0,pos);
        t2=s.substr(pos+1);
       // while(ss>>t)t2+=t;
        if(t1==word1)lib.erase(lib.find(ma[t2]) );
        else if(t1==word2)rtu.insert(ma[t2]);
        else print();
    }
}
int main()
{
    init();
    work();
    return 0;
}
/*
"The Canterbury Tales" by Chaucer, G.
"Algorithms" by Sedgewick, R.
"The C Programming Language" by Kernighan, B. and Ritchie, D.
END
BORROW "Algorithms"
BORROW "The C Programming Language"
RETURN "Algorithms"
RETURN "The C Programming Language"
SHELVE
END
*/
/*AC
"The Canterbury Tales" by Chaucer, G.
"Algorithms" by Sedgewick, R.
"The C Programming Language" by Kernighan, B. and Ritchie, D.
END
BORROW "Algorithms"
BORROW "The C Programming Language"
RETURN "Algorithms"
RETURN "The C Programming Language"
SHELVE
Put "The C Programming Language" after "The Canterbury Tales"
Put "Algorithms" after "The C Programming Language"
END
END
*/

Bug Hunt UVA - 1596map&&stack&&模擬

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

題意:

給你一個程序,要你找bug。

  1. 有數組定義。arr【number】
  2. 有數組賦值 arr【expression】=expression。

思路:

由於expression可能會套娃,所以要遞歸到只剩,數字。
細節很多。

  1. 數組不能越界,
  2. 等式的右邊:數組要滿足之前被賦值過。
  3. 假如arr【exprssion1】=arr2【expression2】中的expression1爲數組,:那麼同樣要滿足條件2.

函數:

  1. 分割操作,可以寫個函數
  2. 檢查是否1右bug可以寫個函數。
  3. 數組初始化可以寫個函數,
  4. 最後有了整體框架,就可以開始碼了。

反思

s.find(),找不到時,返回的是npos

AC

#include <iostream>
#include <string>
#include <map>
#define  mp make_pair
#define For(i,x,y) for(register int i=(x); i<=(y); i++)
using namespace std;
typedef pair<string,int>pa;
string s[1010];
map<string,int>asize;
map<pa,int>arr;
int cnt;
void get(const string s, string &t1, string &t2)
{
    int pos=0;
    if(s.find("[")!=s.npos)
    {
        pos=s.find("["),t1=s.substr(0,pos);
        t2=s.substr(pos+1,s.size()-1-pos-1);
    }//len=s.size()-1-pos-1;
    else{t1="";t2=s;}
}
void init(const string &s)
{
    string t1,t2;
    get(s,t1,t2);
    int len=stoi(t2);
    asize[t1]=len-1;
    //cout<<t1<<' '<<t2<<endl;
    return ;
}
int check(const string &s,int &flag)
{
    if(flag==0||s=="")return 0;
    int len;
    string t1,t2;
    get(s,t1,t2);
    if(t1=="")return (int)stoi(t2);
    if(!asize.count(t1)){flag=0;return 0;}
    if(t2[0]>='a'&&t2[0]<='z'||t2[0]>='A'&&t2[0]<='Z')len=check(t2,flag);
    else len=stoi(t2);
    if(!arr.count(mp(t1,len))){flag=0;return 0;}
    if(asize[t1]<len){flag=0;return 0;}
    return arr[mp(t1,len)];
}
void find(string &s,int &len,int &flag)
{
    string t1,t2;
    get(s,t1,t2);
    len=check(t2,flag);
    s=t1;
    if(!asize.count(t1))flag=0;
    if(asize[t1]<len)flag=0;
    return ;
}
int main()
{
    cnt=1;
    while(getline(cin,s[cnt])&&s[cnt]!=".")
    {
        cnt++;
        string t1,t2;
        asize.clear();
        arr.clear();
        int flag=1,ans=0,pos;
        while(getline(cin,s[cnt])&&s[cnt]!=".")cnt++;
        cnt--;
        //For(i,1,cnt)cout<<s[i]<<endl;
        //cout<<cnt<<endl;
        For(i,1,cnt)
        {
            if(s[i].find('=')==s[i].npos)init(s[i]);
            else
            {
               // cout<<s[i]<<endl;
                int len1,len2;
                pos=s[i].find("=");
                t1=s[i].substr(0,pos);
                find(t1,len1,flag);
                t2=s[i].substr(pos+1);
                len2=check(t2,flag);
               // cout<<t1<<'['<<len1<<']'<<" "<<endl;
                //cout<<t2<<'['<<len2<<']'<<" "<<endl;
                if(flag==0)
                {
                    ans=i;
                    break;
                }
                arr[mp(t1,len1)]=len2;
//cout<<endl<<endl;
            }
        }
        if(flag)cout<<0<<endl;
        else cout<<ans<<endl;
        cnt=1;
    }
    return 0;
}
/*
a[3]
a[0]=a[1]
.
x[1]
x[0]=x[0]
.
a[0]
a[0]=1
.
b[2]
b[0]=2
b[1]=b[b[0]]
b[0]=b[1]
.
g[2]
G[10]
g[0]=0
g[1]=G[0]
.
a[2147483647]
a[0]=1
B[2]
B[a[0]]=2
a[B[a[0]]]=3
a[2147483646]=a[2]
.
.
*/
/*
2 2 2 3 4 0
*/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章