紫薯 第五章 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
*/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章