第一屆C語言比賽答案

LinuxDevqqqqqq發表於2018-11-22

嵌入式Linux:第一屆C語言比賽


題目連結

密碼 2580

下面給出題目解析和答案

題目 1

題目描述

This English game is a simple English words connection game.

The rules are as follows: there are N English words in a dictionary, and every word has its own weight v. There is a weight if the corresponding word is used. Now there is a target string X. You have to pick some words in the dictionary, and then connect them to form X. At the same time, the sum weight of the words you picked must be the biggest.

輸入

There are several test cases. For each test, N (1<=n<=1000) and X (the length of x is not bigger than 10000) are given at first. Then N rows follow. Each row contains a word wi (the length is not bigger than 30) and the weight of it. Every word is composed of lowercases. No two words in the dictionary are the same.

輸出

For each test case, output the biggest sum weight, if you could not form the string X, output -1.

 

題目翻譯

輸入一個數字 N 和一個長字串 XXXXXXXXXX

然後輸入 N 個子字串 TTTTT ,並給出每個子字串的權值 Y

然後輸出長字串的最大權值 S

答案提供者

<img src=" data-caption="" data-size="normal" data-rawwidth="111" data-rawheight="92" width="111">

參考程式碼

#include <stdio.h>

#include <string.h>

 

#define MAX_STR_LEN 10001

#define MAX_TRIE_ENTRY_LEN 31

#define MAX_TRIE_NODE 300001

#define MAX_ALPHA 26

 

int g_trie[MAX_TRIE_NODE][MAX_ALPHA];     /*  字典樹 */

int trie_vals[MAX_TRIE_NODE];             /*  字典樹上關鍵字權值 */

int curr_node  = ;                            /*  字典樹當前分配的節點編號 */

 

void build_trie ( char * s,  int val)         /*  插入單詞 S 到字典樹中 */

{

      int root  = ;

      char * = s;

      int num  = ;

      while ( * != '\0' )

     {

         num  = * - 'a' ;

          if (g_trie[root][num]  == )

         {

              g_trie[root][num]  = ++ curr_node;

         }

         root  = g_trie[root][num];

         p ++ ;

     }

     trie_vals[root]  = val;      /* 記錄權值,也可以用來標記字典樹中關鍵字結束(即葉子節點) */

      return ;

}

 

int main ()

{

      int n, v, len, num, i, j, kroot;

      int dp[MAX_STR_LEN];

      char target[MAX_STR_LEN];

      char trie_entry[MAX_TRIE_ENTRY_LEN];

     

      while ( ~ scanf( "%d %s" & n, target))

     {

         len  = strlen(target);

          /* 初始化葉子節點 */

         curr_node  = ;

         memset(g_trie,  sizeof ( int * MAX_TRIE_NODE  * MAX_ALPHA);

         memset(trie_vals,  sizeof ( int * MAX_TRIE_NODE);

          for (i  = ; i  < n; i ++ )

         {

              scanf( "%s %d" , trie_entry,  & v);

              build_trie(trie_entry, v);

         }

         

         memset(dp,  sizeof ( int * MAX_STR_LEN);     /* dp[i] 表示 target 字串長度為 i 時的最優解 */

          /* 在字典樹中查詢 target i-j 的子串 */

          for (i  = ; i  < len; i ++ )

         {

              kroot  = ;

               if ( != && == dp[i])   /*  如果 dp[i] ,即 target 0-i 的子串沒有解,沒必要再查詢 i-j 子串的權值 */

              {

                   continue ;

              }

               for (j  = i; j  < (i  + MAX_TRIE_ENTRY_LEN  - 1 && < len; j ++ )

              {

                   if ( == (kroot  = g_trie[kroot][target[j]  - 'a' ]))     /* j 個字母沒有在字典樹上找到,即 i-j 字串沒在字串上找到 */

                  {

                        break ;

                  }

                  

                   /* 如果 trie_vals[kroot] ,即子串 i-j 只匹配了某關鍵字的字首,沒有全詞匹配得到 */

                   /* dp[j + 1] = max(dp[i] + trie_vals[kroot], dp[j + 1]) ,如果長度 i 的最優解加上 i-j 字串的權值更大,就取該值 */

                   if (trie_vals[kroot]  && dp[j  + 1 < dp[i]  + trie_vals[kroot])

                  {

                       dp[j  + 1 = dp[i]  + trie_vals[kroot];

                  }

              }

         }

         

          if (dp[len]  == )

              dp[len] -- ;

         printf( "%d\n" , dp[len]);

     }

      return ;

}

 

/*

 

1 aaaa

a 2

3 aaa

a 2

aa 5

aaa 6

4 abc

a 1

bc 2

ab 4

c 1

3 abcd

ab 10

bc 20

cd 30

3 abcd

cd 100

abc 1000

bcd 10000

 

output:

8

7

5

40

-1

 

*/

題目 2

題目描述

此刻你正在為瀋陽理工開發一個 BBS ,為了網路文明並避免一些敏感詞彙, BBS 的聊天中不能出現某些違禁用語。所以你的系統設計為由管理員輸入若干的違禁詞彙,對於帖子中的違禁詞彙,系統只顯示第一個字元,其他字元全部用 * 代替。注意查詢違禁詞彙時是不考慮大小寫的,但修改時則要保留大小寫。比如 love 是違禁詞彙,則 Love love 都是違禁詞語,而帖子中的 love 被輸出為 l*** ,而 Love 輸出 L*** 。現在就看你的啦!

輸入

輸入資料只有一組,第一行為一個正整數 n n<=1000 ),接下來有 n 行,每行有一個英文單詞,由若干個英文字母組成,不含空格(單詞長度不超過 20 )。

 

接下來有若干段需要處理的文字,處理到檔案結束為止,字元個數不超過 10000 個。

輸出

輸出處理後的文字,除了違禁用語,其他文字和格式不變。

 

題目解析

這個題目相對題目 1 相對簡單,但是坑也比較多,寫答案的時候要特別注意

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31561984/viewspace-2221176/,如需轉載,請註明出處,否則將追究法律責任。

相關文章