ACM集训STL(1)学习杂记(一)——A题~D题

STL(1)

(A)圆桌问题

应该就是道简单题,目的是熟悉stl容器vector。

圆桌问题

圆桌上围坐着2n个人。其中n个人是好人,另外n个人是坏人。如果从第一个人开始数数,数到第m个人,则立即处死该人;然后从被处死的人之后开始数数,再将数到的第m个人处死……依此方法不断处死围坐在圆桌上的人。试问预先应如何安排这些好人与坏人的座位,能使得在处死n个人之后,圆桌上围坐的剩余的n个人全是好人。

Input

多组数据,每组数据输入:好人和坏人的人数n(<=32767)、步长m(<=32767);

Output

对于每一组数据,输出2n个大写字母,‘G’表示好人,‘B’表示坏人,50个字母为一行,不允许出现空白字符。相邻数据间留有一空行。

Sample Input

2 3
2 4

Sample Output

GBBG 

BGGB

最终AC代码

#include <iostream>
#include <vector>
using namespace std;
int main()
{
    int m,n,a=0;
    while(cin>>n>>m)
    {
        vector<int> vec1(2*n);
        vector<char> vec2(2*n,'G');
        {
            int i=0;
            for(vector<int>::iterator it=vec1.begin();it!=vec1.end();++it)
            {
                *it=i;
                ++i;
            }
        }
        for(int i=0,k=2*n,j=(m-1)%k+1;i<n;++i)
        {
            vec2[vec1[j-1]]='B';
            vec1.erase(vec1.begin()+j-1);
            --k;
            j=(j+m-2)%k+1;
        }
        a=0;
        for(vector<char>::iterator it=vec2.begin();it!=vec2.end();++it,++a)
        {
            if(a==50) 
            {
                cout<<endl;
                a=0;
            }
            cout<<*it;
        }
        cout<<endl<<endl;
    }
    return 0;
}

备注

 刚开始接触stl,一直用push_back去删除数据,导致这题卡了几天,至少现在不会犯这样的错误了:D。


(B)Encoding

现在看还是道简单题,此题目的在于对string容器的熟悉。

Encoding

Given a string containing only 'A' - 'Z', we could encode it using the following method:
1. Each sub-string containing k same characters should be encoded to "kX" where "X" is the only character in this sub-string.
2. If the length of the sub-string is 1, '1' should be ignored.

Input

The first line contains an integer N (1 <= N <= 100) which indicates the number of test cases. The next N lines contain N strings. Each string consists of only 'A' - 'Z' and the length is less than 10000.

Output

For each test case, output the encoded string in a line.

Sample Input

2
ABC
ABBCCC

Sample Output

ABC
A2B3C

最终AC代码

#include <iostream>
#include <vector>
#include <cstring>
#include <string>
using namespace std;
inline void substring(char a,int b)
{
    if(b!=1) cout<<b;
    cout<<a;
}
int main()
{
    int n;
    char a;
    string m;
    cin>>n;
    cin.get();
    for(int i=0;i<n;++i)
    {
        getline(cin,m);
        a=m[0];
        for(unsigned int i=1,j=1;i<=strlen(m.c_str());++i)
        {
            if (a==m[i]) ++j;
            else
            {
                substring(a,j);
                a=m[i];
                j=1;
            }
        }
        cout<<endl;
    }
}

备注

第一次提交CE,报错是

0_0_34754783_15604.cpp
0_0_34754783_15604.cpp(19) : error C3861: “getline”:  找不到标识符

后来搜索发现这里使用的getline函数定义在头文件string里(此外getline在头文件istream还有一个重载)。

虽然一般来说会使用万能头文件bits/stdc++.h,但练习的时候还是熟悉一下各个函数所在的头文件比较好。


(C)Easier Done Than Said?

初见有种复杂的感觉,但分步解决之后就好很多了。心态很重要。

Easier Done Than Said?

Password security is a tricky thing. Users prefer simple passwords that are easy to remember (like buddy), but such passwords are often insecure. Some sites use random computer-generated passwords (like xvtpzyo), but users have a hard time remembering them and sometimes leave them written on notes stuck to their computer. One potential solution is to generate "pronounceable" passwords that are relatively secure but still easy to remember.
FnordCom is developing such a password generator. You work in the quality control department, and it's your job to test the generator and make sure that the passwords are acceptable. To be acceptable, a password must satisfy these three rules:
It must contain at least one vowel.
It cannot contain three consecutive vowels or three consecutive consonants.
It cannot contain two consecutive occurrences of the same letter, except for 'ee' or 'oo'.
(For the purposes of this problem, the vowels are 'a', 'e', 'i', 'o', and 'u'; all other letters are consonants.) Note that these rules are not perfect; there are many common/pronounceable words that are not acceptable.

Input

The input consists of one or more potential passwords, one per line, followed by a line containing only the word 'end' that signals the end of the file. Each password is at least one and at most twenty letters long and consists only of lowercase letters.

Output

For each password, output whether or not it is acceptable, using the precise format shown in the example.

Sample Input

a
tv
ptoui
bontres
zoggax
wiinq
eep
houctuh
end

Sample Output

<a> is acceptable.
<tv> is not acceptable.
<ptoui> is not acceptable.
<bontres> is not acceptable.
<zoggax> is not acceptable.
<wiinq> is not acceptable.
<eep> is acceptable.
<houctuh> is acceptable.

最终AC代码

#include <iostream>
#include <vector>
#include <cstring>
#include <string>
using namespace std;
int main()
{
    size_t npos = -1;
    string m,p;
    bool s;
    while(getline(cin,m))
    {
        p=m;
        s=1;
        if (m=="end") break;
        if (m.find('a')==npos&&
            m.find('e')==npos&&
            m.find('i')==npos&&
            m.find('o')==npos&&
            m.find('u')==npos)
        {
            s=0;
        }

        for (string::iterator i=m.begin();i!=m.end()-1;++i)
        {
            if (m.length()<2) break;
            if (*i==*(i+1)&&*i!='e'&&*i!='o') s=0;
        }

        for (string::iterator i=m.begin();i!=m.end();++i)
        {
            if(*i=='a'||*i=='e'||*i=='i'||*i=='o'||*i=='u') *i='a';
            else *i='b';
        }
        for (string::iterator i=m.begin();i!=m.end()-2;++i)
        {
            if (m.length()<3) break;
            if (*i==*(i+1)&&*i==*(i+2)) s=0;
        }
        if (s==1) cout<<"<"<<p<<"> is acceptable."<<endl;
        else cout<<"<"<<p<<"> is not acceptable."<<endl;
    }
}

备注

这道题里比较多地使用了迭代器(iterator),其实这里使用下标访问string的元素也是可以的。这样一看其实也是一道简单题。


(D)SPY

这道题遇到的主要问题是如何读取一行中数量未知的多个数据。问题反而不在stl上了。

SPY

The National Intelligence Council of X Nation receives a piece of credible information that Nation Y will send spies to steal Nation X’s confidential paper. So the commander of The National Intelligence Council take measures immediately, he will investigate people who will come into NationX. At the same time, there are two List in the Commander’s hand, one is full of spies that Nation Y will send to Nation X, and the other one is full of spies that Nation X has sent to Nation Y before. There may be some overlaps of the two list. Because the spy may act two roles at the same time, which means that he may be the one that is sent from Nation X to Nation Y, we just call this type a “dual-spy”. So Nation Y may send “dual_spy” back to Nation X, and it is obvious now that it is good for Nation X, because “dual_spy” may bring back NationY’s confidential paper without worrying to be detention by NationY’s frontier So the commander decides to seize those that are sent by NationY, and let the ordinary people and the “dual_spy” in at the same time .So can you decide a list that should be caught by the Commander?
A:the list contains that will come to the NationX’s frontier.
B:the list contains spies that will be sent by Nation Y.
C:the list contains spies that were sent to NationY before.

Input

There are several test cases.
Each test case contains four parts, the first part contains 3 positive integers A, B, C, and A is the number which will come into the frontier. B is the number that will be sent by Nation Y, and C is the number that NationX has sent to NationY before.
The second part contains A strings, the name list of that will come into the frontier.
The second part contains B strings, the name list of that are sent by NationY.
The second part contains C strings, the name list of the “dual_spy”.
There will be a blank line after each test case.
There won’t be any repetitive names in a single list, if repetitive names appear in two lists, they mean the same people.

Output

Output the list that the commander should caught (in the appearance order of the lists B).if no one should be caught, then , you should output “No enemy spy”

Sample Input

8 4 3
Zhao Qian Sun Li Zhou Wu Zheng Wang
Zhao Qian Sun Li
Zhao Zhou Zheng
2 2 2
Zhao Qian
Zhao Qian
Zhao Qian

Sample Output

Qian Sun Li
No enemy spy

最终AC代码

#include <iostream>
#include <vector>
#include <cstring>
#include <string>
using namespace std;
int main()
{
    vector<string> p,q,r;
    unsigned long long a,b,c,u,t;
    string s;
    while(cin>>a>>b>>c)
    {
        p.clear();
        q.clear();
        r.clear();
        for(unsigned long long i=0;i<a;++i)
        {
            cin>>s;
            p.push_back(s);
        }
        for(unsigned long long i=0;i<b;++i)
        {
            cin>>s;
            q.push_back(s);
        }
        for(unsigned long long i=0;i<c;++i)
        {
            cin>>s;
            r.push_back(s);
        }
        t=1;
        if(q.size()!=0)
        {
            int v=0;
            for(unsigned long long i=0;i<q.size();++i)
            {
                u=1;
                for(unsigned long long j=0;j<p.size();++j)
                    if(q[i]==p[j]) {u=0;break;}
                for(unsigned long long j=0;j<r.size();++j)
                    if(q[i]==r[j]) {u=1;break;}
                if(u==0) 
                {
                    if(v==1) cout<<" ";
                    else v=1;
                    cout<<q[i];
                    t=0;
                }
            }
        }
        if(t==1) cout<<"No enemy spy";
        cout<<endl;
    }
}

备注

前几次提交都是RE(运行时错误 Runtime Error),错当成了TLE(超出时间限制 Time Limit Exceeded)。改了老半天,RE的原因是下标越界,一开始使用j作为变量循环的时候,判断条件是j != r.end(),实际运行时p的大小会改动,导致j跳过p.end(),最后的解决办法是将条件改为

p.size()。最终AC代码去掉了了改动p大小的部分(所以这里使用j != p.end()也是可行的),但是保留了判断条件。


第一次写博客就先写这点。

路漫漫其修远兮,一切都只是开始,想学懂学好还需努力。

加油。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值