有道难题资格赛(1)

 

参与人数
4849
提交次数
25797

 

分数   名次

1000  1~239

700   ~265

...

400         ~ 450

 

编号 标题 分数 通过率 通过人数 提交次数
A 另类的异或 150 29% 3405 11947
B 有道搜索框 300 13% 1439 11065
C 最大和子序列 550 10% 274 2785

A:另类的异或

时间限制:
1000ms
内存限制:
131072kB
描述
对于普通的异或,其实是二进制的无进位的加法
这里我们定义一种另类的异或A op B, op是一个仅由^组成的字符串,如果op中包含n个^,那么A op B表示A和B之间进行n+1进制的无进位的加法。
下图展示了3 ^ 5 和 4 ^^ 5的计算过程
有道难题资格赛(1)
输入
第一行有一个正整数T, 表示下面共有T组测试数据。
接下来T行,每行有一组测试数据,是由空格隔开的三个部分组成:
A B C
A和C是两个十进制整数,B是一个字符串,由n个^组成
1 <= T <= 100, 0<=A,B<2^30, 1<=n<=1000
输出
每个测试数据输出一行,包含一个数字,即该数据的结果,用十进制表示。
样例输入
2
3 ^ 5
4 ^^ 5
样例输出
6
有道难题资格赛(1) 代码
#include  < stdio.h >
#include 
< string .h >
#include 
< memory.h >

// 将数字从十进制转换到制定进制
// input:
// n: 要转换的数字(十进制)
// m: 要转换的进制
// output:
// a,l: 要求进制的数字,和位数,[0]为最低位
void  split( int  n,  int  m, int  a[], int   & l)
{
    l
= 0 ;
    
for (;n;n /= m)
    {
        a[l
++ ] = n % m;
    }
}

void  print( int  a[], int  l)
{
    
for ( int  i = 0 ;i < l;i ++ )
        printf(
" %d  " ,a[i]);
    printf(
" \n " );
}

// 将指定进制的数字做xor运算
// input:
// a,n1,b,n2
// m
// output:
// c
int  xor( int   const  a[], int  n1,  int    const  b[], int  n2,  int  m,  int  c[])
{
    
int  k = n1 > n2 ? n1:n2;
    
for ( int  i = 0 ;i < k;i ++ )
    {
        c[i]
= (a[i] + b[i]) % m;
    }
    
return  k;
}

int  A[ 50 ];
int  nA = 0 ;
int  nB = 0 ;
int  B[ 50 ];
int  nC = 0 ;
int  C[ 50 ];

// 将数字从指定进制转换到十进制
int  merge( int   const  a[], int  n1,  int  m)
{
    
int  r = 0 ;
    
for ( int  i = 0 ;i < n1;i ++ )
    {
        r 
= r * m + a[n1 - 1 - i];
    }
    
return  r;
}

int  main( int  argc,  char   * argv[])
{
    
int  T;
    scanf(
" %d " , & T);
    
while (T -- )
    {
        
int  a,b = 0 ,m;
        
char  s[ 1000 + 1 ];
        scanf(
" %d %s %d " , & a,s, & b);
        m
= strlen(s) + 1 ;
        
// printf("a %d b %d m %d\n",a,b,m);
        memset(A, 0 , sizeof (A));
        memset(B,
0 , sizeof (B));
        memset(C,
0 , sizeof (C));
        split(a,m,A,nA);
        split(b,m,B,nB);
        
// print(A,nA);
        
// print(B,nB);
        nC = xor(A,nA,B,nB,m,C);
        
// print(C,nC);
         int  r = merge(C,nC,m);
        printf(
" %d\n " ,r);
    }

    
return   0 ;
}



B:有道搜索框

时间限制:
1000ms
内存限制:
131072kB
描述
在有道搜索框中,当输入一个或者多个字符时,搜索框会出现一定数量的提示,如下图所示:
有道难题资格赛(1)

现在给你N个单词和一些查询,请输出提示结果,为了简化这个问题,只需要输出以查询词为前缀的并且按字典序排列的最前面的8个单词,如果符合要求的单词一个也没有请只输出当前查询词。
输入
第一行是一个正整数N,表示词表中有N个单词。
接下来有N行,每行都有一个单词,注意词表中的单词可能有重复,请忽略掉重复单词。所有的单词都由小写字母组成。
接下来的一行有一个正整数Q,表示接下来有Q个查询。
接下来Q行,每行有一个单词,表示一个查询词,所有的查询词也都是由小写字母组成,并且所有的单词以及查询的长度都不超过20,且都不为空
其中:N<=10000,Q<=10000
输出
对于每个查询,输出一行,按顺序输出该查询词的提示结果,用空格隔开。
样例输入
10
a
ab
hello
that
those
dict
youdao
world
your
dictionary
6
bob
d
dict
dicti
yo
z
样例输出
bob
dict dictionary
dict dictionary
dictionary
youdao your
z
有道难题资格赛(1) 代码
//  test.cpp : Defines the entry point for the console application.
//

#include 
" stdafx.h "

#include 
< stdio.h >
#include 
< string .h >
#include 
< memory.h >
#include 
< assert.h >

struct  node
{
    
char  end;
    
long  child[ 26 ];         // idx of its child
    node()
        :end(
0 )
    {
        memset(child,
0 , sizeof (child));
    }
}nodes[
10000 * 20 ];
long  n = 0 ;

void  insert( char   const  s[])
{
    
long  idx = 0 ;
    
for ( int  i = 0 ,m = strlen(s);i < m;i ++ )
    {
        
long   * pidx =& nodes[idx].child[s[i] - ' a ' ];
        
if ( * pidx == 0 )
        {
            idx
=* pidx =++ n;
        }
        
else
            idx
=* pidx;
        
if (i == m - 1 )
            nodes[idx].end
= 1 ;
    }
}

char  str[ 20 ];
int  nStr = 0 ;
void  print( long  idx)
{
    
if (nodes[idx].end)
    {
        str[nStr]
= 0 ;
        printf(
" %s  " ,str);
    }
    
    
for ( int  i = 0 ;i < 26 ;i ++ )
    {
        
long  idx2 = nodes[idx].child[i];
        
if (idx2)
        {
            str[nStr
++ ] = i + ' a ' ;
            print(idx2);
            nStr
-- ;
        }
    }
}

void  srch( char   const  s[])
{
    
bool  find = true ;
    
long  idx = 0 ;
    
for ( int  i = 0 ,m = strlen(s);i < m;i ++ )
    {
        idx
= nodes[idx].child[s[i] - ' a ' ];
        
if ( ! idx)
        {
            find 
=   false ;
            
break ;
        }
    }

    
if ( ! find)
        printf(
" %s\n " ,s);
    
else
    {
        strcpy(str,s);
        nStr
= strlen(s);
        print(idx);
        printf(
" \n " );
    }
}

int  main( int  argc,  char   * argv[])
{
    
int  N;
    scanf(
" %d " , & N);
    
while (N -- )
    {
        
char  s[ 20 ];
        scanf(
" %s " ,s);
        insert(s);
    }

    
// srch("");

    scanf(
" %d " , & N);
    
while (N -- )
    {
        
char  s[ 20 ];
        scanf(
" %s " ,s);
        srch(s);
    }

    
return   0 ;
}



C:最大和子序列

时间限制:
1000ms
内存限制:
131072kB
描述
给一个整数数组A={a1,a2,…an}, 将这个数组首尾相接连成一个环状,它的一个子序列是指这个数组连续的一段,比如a2,a3…ak,或者an,a1…ai。请从这个环上选取两个不重叠的非空子序列,使这两个子序列中的所有数字之和最大。
在三个样例中分别选取的子序列是:
样例一: {a1} {a3}
样例二: {a1} {a3}
样例三: {a5,a1} {a3}
输入
输入的第一行包含一个正整数T(1<=T<=40),表示有T组测试数据。
接下来每个测试数据包含两行,第一行是一个正整数n(2<=n<=50000), 第二行是用空格隔开的数组A的n个数,依次为a1,a2,…an (|ai|<=10000)。
输出
每组数据输出一行,包含一个数,即所求的这两个子序列的元素之和。
样例输入
3
3
1 -1 0
4
1 -1 1 -1
5
1 -1 1 -1 1
样例输出
1
2
3
提示

你可能感兴趣的:(有道难题资格赛(1))