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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章