2018-07-23 STL练习题题解

  • A  -- Game Rank

  • Description

The gaming company Sandstorm is developing an online two player game. You have been asked to implement the ranking system. All players have a rank determining their playing strength which gets updated after every game played. There are 25 regular ranks, and an extra rank, “Legend”, above that. The ranks are numbered in decreas- ing order, 25 being the lowest rank, 1 the second highest rank, and Legend the highest rank.

Each rank has a certain number of “stars” that one needs to gain before advancing to the next rank. If a player wins a game, she gains a star. If before the game the player was on rank 6-25, and this was the third or more consecutive win, she gains an additional bonus star for that win. When she has all the stars for her rank (see list below) and gains another star, she will instead gain one rank and have one star on the new rank.

For instance, if before a winning game the player had all the stars on her current rank, she will after the game have gained one rank and have 1 or 2 stars (depending on whether she got a bonus star) on the new rank. If on the other hand she had all stars except one on a rank, and won a game that also gave her a bonus star, she would gain one rank and have 1 star on the new rank. If a player on rank 1-20 loses a game, she loses a star. If a player has zero stars on a rank and loses a star, she will lose a rank and have all stars minus one on the rank below. However, one can never drop below rank 20 (losing a game at rank 20 with no stars will have no effect).

If a player reaches the Legend rank, she will stay legend no matter how many losses she incurs afterwards. The number of stars on each rank are as follows:

• Rank 25-21: 2 stars

• Rank 20-16: 3 stars

• Rank 15-11: 4 stars

• Rank 10-1: 5 stars

A player starts at rank 25 with no stars. Given the match history of a player, what is her rank at the end of the sequence of matches?

  • Input

There will be several test cases. Each case consists of a single line describing the sequence of matches. Each character corre- sponds to one game; ‘W’ represents a win and ‘L’ a loss. The length of the line is between 1 and 10 000 characters (inclusive).

  • Output

Output a single line containing a rank after having played the given sequence of games; either an integer between 1 and 25 or “Legend”.

  • Sample Input

WW

WWW

WWWW

WLWLWLWL

WWWWWWWWWLLWW

WWWWWWWWWLWWL

  • Sample Output

25

24

23

24

19

18

  • 题目理解

      该题类似于王者荣耀的上星过程,当你超过你所需要的升级数量即可升一级并且扣除升级所消耗的星星。这里需要使用变量   记下连续赢的局数,当你是6-25级并且连续胜利三局或者以上的时候将获得额外的一颗星星。当你失败的时候回失去一颗星星,如果当前等级下你没有星星将会降一个等级,并且归还之前升级所消耗的星星,但是需要减去当前消耗的一颗星星。注意当20级没有星星时不会有任何影响,并且更低等级也不会损失星星。这题直接模拟就可以但是很多细节部分需要思考清楚

#include<cstdio>
#include<cstring>
const int maxn=10005;
char strs[maxn];
int main()
{
    int star,win,level;
    while(scanf("%s",strs)!=EOF){
        star=0,win=0,level=25;
        int len=strlen(strs);
        for(int i=0;i<len;++i){
            if(level==0) break;//这里先用0代替legend
            if(strs[i]=='W'){
                win++;
                if(level>=6&&level<=25&&win>=3) star+=2;
                else ++star;
                if(level>=21&&level<=25&&star>2){
                    star-=2;
                    --level;
                }
                if(level>=16&&level<=20&&star>3){
                    star-=3;
                    --level;
                }
                if(level>=11&&level<=15&&star>4){
                    star-=4;
                    --level;
                }
                if(level>=1&&level<=10&&star>5){
                    star-=5;
                    --level;
                }
            }else{
                win=0;
                if(level>=21)continue;
                star--;
                if(star<0){
                  if(level==20){
                    star=0;
                  }
                  if(level>=15&&level<=19){
                    level++;
                    star = 2;
                  }
                  if(level>=10&&level<15){
                    level++;
                    star = 3;
                  }
                  if(level>=1&&level<=9){
                    level++;
                    star = 4;
                  }
                }
            }
        }
        if(level)printf("%d\n",level);
        else   printf("Legend\n");
    }
    return 0;
}

 

  • B  -- Where is the Marble?

  • Description

Raju and Meena love to play with Marbles. They have got a lot of marbles with numbers written on them. At the beginning, Raju would place the marbles one after another in ascending order of the numbers written on them. Then Meena would ask Raju to find the first marble with a certain number. She would count 1...2...3. Raju gets one point for correct answer, and Meena gets the point if Raju fails. After some fixed number of trials the game ends and the player with maximum points wins. Today it’s your chance to play as Raju. Being the smart kid, you’d be taking the favor of a computer. But don’t underestimate Meena, she had written a program to keep track how much time you’re taking to give all the answers. So now you have to write a program, which will help you in your role as Raju.

  • Input

There can be multiple test cases. Total no of test cases is less than 65. Each test case consists begins with 2 integers: N the number of marbles and Q the number of queries Mina would make. The next N lines would contain the numbers written on the N marbles. These marble numbers will not come in any particular order. Following Q lines will have Q queries. Be assured, none of the input numbers are greater than 10000 and none of them are negative. Input is terminated by a test case where N = 0 and Q = 0.

  • Output

For each test case output the serial number of the case. For each of the queries, print one line of output. The format of this line will depend upon whether or not the query number is written upon any of the marbles. The two different formats are described below:

• ‘x found at y’, if the first marble with number x was found at position y. Positions are numbered 1,2,...,N.

• ‘x not found’, if the marble with number x is not present. Look at the output for sample input for details.
 

  • Sample Input

4 1 2 3 5 1 5

5 2 1 3 3 3 1 2 3

0 0

  • Sample Output

CASE# 1:

5 found at 4

CASE# 2:

2 not found

3 found at 3

  • 题目理解

      题目大意得到第一个相等的数位置,如果找不到显示未找到。直接使用lower_bound再判断一下定位的数是否等于查找数或者已经到数组尾

#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
const int maxn=10005;
int a[maxn];
int main()
{
    int n,q,x;
    int Case=0;
    while(scanf("%d%d",&n,&q)!=EOF&&n){
        for(int i=0;i<n;++i) scanf("%d",&a[i]);
        sort(a,a+n); //从小排大
        //for(int i=0;i<n;++i) printf("%d ",a[i]);
        printf("CASE# %d:\n",++Case);
        for(int i=0;i<q;++i){
            scanf("%d",&x);
            int lct=lower_bound(a,a+n,x)-a;
            //printf("!!%d  %d\n",lct,a[lct]);
            if(x!=a[lct])
                printf("%d not found\n",x);
            else if(lct>=n)
                printf("%d not found\n",x);
            else
                printf("%d found at %d\n",x,lct+1);
        }
    }
    return 0;
}

 

  • C  -- Bit String Reordering

  • Description

You have to reorder a given bit string as specified. The only operation allowed is swapping adjacent bit pairs. Please write a program that calculates the minimum number of swaps required. The initial bit string is simply represented by a sequence of bits, while the target is specified by a run-length code. The run-length code of a bit string is a sequence of the lengths of maximal consecutive sequences of zeros or ones in the bit string. For example, the run-length code of “011100” is “1 3 2”. Note that there are two different bit strings with the same run-length code, one starting with zero and the other starting with one. The target is either of these two. In Sample Input 1, bit string “100101” should be reordered so that its run-length code is “1 3 2”, which means either “100011” or “011100”. At least four swaps are required to obtain “011100”. On the other hand, only one swap is required to make “100011”. Thus, in this example, 1 is the answer.

  • Input

The input consists of several tests case. For each test, the test case is formatted as follows. NM b1 b2 ...bN p1 p2 ...pM ThefirstlinecontainstwointegersN (1≤N ≤15)andM (1≤M ≤N). Thesecondline specifies the initial bit string by N integers. Each integer bi is either 0 or 1. The third line contains the run-length code, consisting of M integers. Integers p1 through pM represent the lengths of consecutive sequences of zeros or ones in the bit string, from left to right. Here, 1≤pj for1≤j≤M and Mj=1pj =N hold. It is guaranteed that the initialbitstring can be reordered into a bit string with its run-length code p1, . . . , pM .

  • Output

Output the minimum number of swaps required.

  • Sample Input

6 3

1 0 0 1 0 1

1 3 2

7 2

1 1 1 0 0 0 0

4 3

15 14

1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 11 1 2

1 1

0

1

  • Sample Output

1

12

7

0

  • 题目理解

首先构造正确答案要么是从0开始要么是从1开始(有可能两种都成立需要判断)

然后从左向右每位对照如果不成立就和后面的序列交换(因为前面是符合情况的不调整的状况下最优)

#include<cstdio>
#include<algorithm>
const int maxn=520520;
using namespace std;
int a[20],ta[20],b[20],lst[20];
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
       int cnt0=0,cnt1=0,cot=0;
       for(int i=0;i<n;++i){
          scanf("%d",&a[i]);
          ta[i]=a[i];
          if(a[i]) ++cnt1;//1的个数
          else ++cnt0;//0的个数
       }
       for(int i=0;i<m;++i){
          scanf("%d",&lst[i]);
          if(i%2==0) cot+=lst[i];//下标从0开始
       }
       int ans0=maxn,ans1=maxn;
       if(cnt0==cot){
         ans0=0;
         int flag=0,ai=0;
         for(int i=0;i<m;++i){
            for(int j=1;j<=lst[i];++j){
                if(a[ai]==flag){//相符合不动
                     ++ai;
                     continue;
                }
                else{
                    int pos;
                    for(pos=ai+1;;++pos)//查找最接近的一个相符合位的位置
                        if(a[pos]==flag)
                          break;
                    ans0+=(pos-ai);
                    a[pos]=!flag;
                    a[ai]=flag;
                    ++ai;
                }
            }
            flag=(!flag);
         }
       }
       if(cnt1==cot){
         ans1=0;
         int flag=1,ai=0;
         for(int i=0;i<m;++i){
            for(int j=1;j<=lst[i];++j){
                if(ta[ai]==flag){//相符合不动
                     ++ai;
                     continue;
                }
                else{
                    int pos;
                    for(pos=ai+1;;++pos)//查找最接近的一个相符合位的位置
                        if(ta[pos]==flag)
                          break;
                    ans1+=(pos-ai);
                    ta[pos]=!flag;
                    ta[ai]=flag;
                    ++ai;
                }
            }
            flag=(!flag);
         }
       }
       printf("%d\n",ans0<ans1?ans0:ans1);
    }
    return 0;
}

 

  • D  -- The Blocks Problem

  • Description

ManyareasofComputerScienceusesimple,abstractdomainsforbothanalyticalandempiricalstudies. For example, an early AI study of planning and robotics (STRIPS) used a block world in which a robot arm performed tasks involving the manipulation of blocks.

In this problem you will model a simple block world under certain rules and constraints. Rather than determine how to achieve a specified state, you will “program” a robotic arm to respond to a limited set of commands.

Theproblemistoparseaseriesofcommandsthatinstructarobotarminhowtomanipulateblocks that lie on a flat table. Initially there are n blocks on the table (numbered from 0 to n−1) with block bi adjacent to block bi+1 for all 0 ≤ i < n−1 as shown in the diagram below:

The valid commands for the robot arm that manipulates blocks are:

• move a onto b where a and b are block numbers, puts block a onto block b after returning any blocks that are stacked on top of blocks a and b to their initial positions.

• move a over b where a and b are block numbers, puts block a onto the top of the stack containing block b, after returning any blocks that are stacked on top of block a to their initial positions.

• pile a onto b where a and b are block numbers, moves the pile of blocks consisting of block a, and any blocks that are stacked above block a, onto block b. All blocks on top of block b are moved to their initialpositions priorto thepile takingplace. Theblocksstackedaboveblock a retaintheir order when moved.

• pile a over b where a and b are block numbers, puts the pile of blocks consisting of block a, and any blocks that are stacked above block a, onto the top of the stack containing block b. The blocks stacked above block a retain their original order when moved.

• quit terminates manipulations in the block world.

Any command in which a = b or in which a and b are in the same stack of blocks is an illegal command. All illegal commands should be ignored and should have no affect on the configuration of blocks.

  • Input

The input begins with an integer n on a line by itself representing the number of blocks in the block world. You may assume that 0 < n < 25. The number of blocks is followed by a sequence of block commands, one command per line. Your program should process all commands until the quit command is encountered. Youmayassumethatallcommandswillbeoftheformspecifiedabove. Therewillbenosyntactically incorrect commands. 

  • Output

The output should consist of the final state of the blocks world. Each original block position numbered i (0 ≤ i < n where n is the number of blocks) should appear followed immediately by a colon. If there is at least a block on it,the  colon must be followed by one space, followed by a list of blocks that appear stacked in that position with each block number separated from other  block numbers bya space. Don’t put any trailing spaces on a line.

There should be one line of output for each block position (i.e., n lines of output where n is the integer on the first line of input). 

  • Sample Input

10

move 9 onto 1

move 8 over 1

move 7 over 1

move 6 over 1

pile 8 over 6

pile 8 over 5

move 2 over 1

move 4 over 9

quit 

  • Sample Output

0: 0

1: 1 9 2 4

2:

3: 3

4:

5: 5 8 7 6

6:

7:

8:

9:

  • 题目理解

模拟,使用vector可变长数组,push_back方法移动箱子;使用函数调用结构更加简洁;紫书110大神代码思路更加巧妙易懂

#include<cstdio>
#include<vector>
using namespace std;
int n;
const int maxn = 26;
// vector 相当于包装好的链表
// vector、map等都是包装好的类,其size保存在一个静态变量中
// 字符串数组相等比较麻烦,所以还是采用是s[0]之类的字符相等比较靠谱
vector<int> blocks[maxn];
void get_row_height(int a,int &r,int &h)//引用返回用法,将修改传进来的值
{
    for(r = 0; r < n; r++)
        for(h = 0; h < blocks[r].size(); h++)
            if(blocks[r][h] == a)
            return;
}
void clear_above(int r,int h)// 将row行height以上的木块全部归位
{
    for(int i = h+1; i < blocks[r].size(); i++){
        int tt = blocks[r][i]; //printf(" !!!!%d\n",tt);
        blocks[tt].push_back(tt);
    }
    blocks[r].resize(h+1);
    return;
}
void move_onto(int r1,int h,int r2)//将row1的height上方(包括自己)移入row2
{
    for(int i = h; i < blocks[r1].size() ; i++){
        blocks[r2].push_back(blocks[r1][i]);
    }
    blocks[r1].resize(h);
    return;
}
void print()
{
    for(int i = 0; i < n; i++){
        printf("%d:",i);
        for(int j = 0; j < blocks[i].size(); j++)
           printf(" %d",blocks[i][j]);
        printf("\n");
    }return;
}
int main()
{
    int a,b;
    char s1[5],s2[5];
    while(scanf("%d",&n) == 1){
        for(int i = 0; i < n; i++){
            blocks[i].resize(0);//清空变长数组
            blocks[i].push_back(i);
        }
        while(scanf("%s",s1) == 1){
            //printf("%s\n",s1);
            if(s1[0] == 'q')
                 break;
            scanf("%d %s %d",&a,s2,&b);
            //printf("%s %d %s %d\n",s1,a,s2,b);
            int ra,ha,rb,hb;
            get_row_height(a,ra,ha);
            get_row_height(b,rb,hb);
            if(ra == rb) continue;
            if(s1[0] == 'm') clear_above(ra,ha);
            if(s2[0] == 'o' && s2[1] == 'n') clear_above(rb,hb);
            move_onto(ra,ha,rb);
            //print();
       }
       print();
    }
    return 0;
}

 

  • E -- Ugly Numbers

  • Description

Ugly numbers are numbers whose only prime factors are 2, 3 or 5. The sequence 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, ...
shows the first 11 ugly numbers. By convention, 1 is included. Write a program to find and print the 1500’th ugly number. 

  • Input

There is no input to this program. 

  • Output

Output should consist of a single line as shown below, with ‘<number>’ replaced by the number computed. 

  • Sample Output

The 1500'th ugly number is <number>.

  • 题目理解

这里可以使用前面的丑数乘以2,3,5生成新的丑数,但是会有很多重复的部分;sort排序然后unique去重,接着从新生成部分重复上面操作,因为前面已经是标准的不会有影响,所以下一个生成元位置就是后一位,循环足够大的数得到1500个丑数,最后直接输出即可,不用考虑时间复杂度的问题

#include<cstdio>
#include<algorithm>
using namespace std;
int main()
{
    long long x=859963392;
    printf("The 1500'th ugly number is %lld.\n",x);
    return 0;
}

后来在紫书里面看到自己曾经做过的代码set去重不需要担心时间复杂度跑不过

// map,vector等使用insert()
// 栈等使用push()
// 栈和队列不能迭代
// 优先队列由大到小排序,使用greater以后从小到大排列
// 自定义结构体,要在其中重载小于号...不能重载大于号
/* friend bool operator< (node a,node b){ 可将小于号看成优先级排序
         return a.x > a.y;
    }*/
#include<set>
#include<cstdio>
#include<vector>
#include<queue>
typedef long long ll;
using namespace std;
int num[3] = {2,3,5};
int main()
{
    set<ll> cnt;
    priority_queue<ll,vector<ll>,greater<ll> >  pq;
    pq.push(1);cnt.insert(1);
    for(int i = 1; i < 1500; i++){
        ll tt = pq.top();
        //printf("%lld\n",tt);
        pq.pop();
        for(int j = 0; j < 3; j++){
            ll x = num[j]*tt;
            if(!cnt.count(x)){
                pq.push(x);
                cnt.insert(x);
            }
        }
    }
    printf("The 1500'th ugly number is %lld.\n",pq.top());
}

 

  • F -- Misha and Changing Handles

  • Description

Misha hacked the Codeforces site. Then he decided to let all the users change their handles. A user can now change his handle any number of times. But each new handle must not be equal to any handle that is already used or that was used at some point.

Misha has a list of handle change requests. After completing the requests he wants to understand the relation between the original and the new handles of the users. Help him to do that.

  • Input

The first line contains integer q (1 ≤ q ≤ 1000), the number of handle change requests.

Next q lines contain the descriptions of the requests, one per line.

Each query consists of two non-empty strings old and new, separated by a space. The strings consist of lowercase and uppercase Latin letters and digits. Strings old and new are distinct. The lengths of the strings do not exceed 20.

The requests are given chronologically. In other words, by the moment of a query there is a single person with handle old, and handle new is not used and has not been used by anyone.

  • Output

In the first line output the integer n — the number of users that changed their handles at least once.

In the next n lines print the mapping between the old and the new handles of the users. Each of them must contain two strings, old and new, separated by a space, meaning that before the user had handle old, and after all the requests are completed, his handle is new. You may output lines in any order.

Each user who changes the handle must occur exactly once in this description.

  • Sample Input

5
Misha ILoveCodeforces
Vasya Petrov
Petrov VasyaPetrov123
ILoveCodeforces MikeMirzayanov
Petya Ivanov

  • Sample Output

3
Petya Ivanov
Misha MikeMirzayanov
Vasya VasyaPetrov123

  • 题目理解

由题意肯定是使用map没得跑了,但是map是根据键值排序的但是为什么样例这样输出,后来觉得应该是new string为标准输出,所以映射应该是将new string映射到old string上面。在映射之前find一下是否到m.end()判断是否存在旧的相关映射,如果有重新映射并且删除旧的关系

#include <cstdio>
#include <map>
#include<iostream>
using namespace std;
int main()
{
    int n;
    string a,b;
    while(scanf("%d",&n)!=EOF){
        string a,b;
        map<string,string> m;
        for(int i=0;i<n;i++)
        {
            cin>>a>>b;
            if(m.find(a)==m.end()) m[b]=a;
            else{
                m[b]=m[a];
                m.erase(a);
            }
        }
        map<string,string>::iterator it;
        cout << m.size() << '\n';
	    for(it=m.begin();it!=m.end();it++) {
		cout << it->second << ' ' << it->first << '\n';
	    }
    }
    return 0;
}

 

  • G -- Ignatius and the Princess II

  • Description

Now our hero finds the door to the BEelzebub feng5166. He opens the door and finds feng5166 is about to kill our pretty Princess. But now the BEelzebub has to beat our hero first. feng5166 says, "I have three question for you, if you can work them out, I will release the Princess, or you will be my dinner, too." Ignatius says confidently, "OK, at last, I will save the Princess."

"Now I will show you the first problem." feng5166 says, "Given a sequence of number 1 to N, we define that 1,2,3...N-1,N is the smallest sequence among all the sequence which can be composed with number 1 to N(each number can be and should be use only once in this problem). So it's easy to see the second smallest sequence is 1,2,3...N,N-1. Now I will give you two numbers, N and M. You should tell me the Mth smallest sequence which is composed with number 1 to N. It's easy, isn't is? Hahahahaha......"
Can you help Ignatius to solve this problem?

  • Input

The input contains several test cases. Each test case consists of two numbers, N and M(1<=N<=1000, 1<=M<=10000). You may assume that there is always a sequence satisfied the BEelzebub's demand. The input is terminated by the end of file.

  • Output

For each test case, you only have to output the sequence satisfied the BEelzebub's demand. When output a sequence, you should print a space between two numbers, but do not output any spaces after the last number.

  • Sample Input

6 4

11 8

  • Sample Output

1 2 3 5 6 4

1 2 3 4 5 6 7 9 8 11 10

  • 题目理解

就是读懂题意就可以了,用next_permutation,但是注意一号已经被占了

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int a[1010];
int main()
{
    int n,m;
    for(int i=0;i<1000;++i) a[i]=i+1;
    while(scanf("%d%d",&n,&m)==2){
       for(int i=0;i<m-1;++i){
       next_permutation(a,a+n);
       //for(int i=0;i<n;++i) printf("%d ",a[i]);
       }
       for(int i=0;i<n-1;++i) printf("%d ",a[i]);
       printf("%d\n",a[n-1]);
       for(int i=0;i<n;++i) a[i]=i+1;
    }
    return 0;
}

 

  • H -- Compound Words

  • Description

You are to find all the two-word compound words in a dictionary. A two-word compound word is a word in the dictionary that is the concatenation of exactly two other words in the dictionary.

  • Input

Standard input consists of a number of lowercase words, one per line, in alphabetical order. There will be no more than 120,000 words.

  • Output

Your output should contain all the compound words, one per line, in alphabetical order.

  • Sample Input

a

alien

born

less

lien

never

nevertheless

new

newborn

the

zebra
 

  • Sample Output

alien

newborn

  • 题目理解

刚开始的时候想将两个词组合然后set里面find然后发现超时;后来将一个单词拆开然后判断是否集合里同时包含两个单词,这样的时间复杂度如果单词不超过一百的话外循环只需要120000*100、内部查找只需要O(2*log120000),不会超时

时间复杂度估计很重要!很重要!很重要

#include <iostream>
#include <cstdio>
#include <set>
using namespace std;
set <string> sets;
int main()
{
    string str,str1,str2;
    while(cin>>str)
        sets.insert(str);
    for(set <string>::iterator it=sets.begin();it!=sets.end();it++)
    {
        str=*it;
        for(int i=0;i<str.length()-1;i++)
        {
            str1=str.substr(0,i+1);
            str2=str.substr(i+1,str.length()-(i+1));
            if(sets.find(str1)!=sets.end()&&sets.find(str2)!=sets.end())
            {
                cout<<str<<endl;
                break;
            }
        }
    }
    return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值