2012年9月亚马逊在线笔试题

前几天我有幸收到亚马逊在线笔试邀请,于是今天上午准时参加了笔试。

 

共2道算法编程题,由于是第一次参加这种笔试,即便是在线,由于时间限制,难免会紧张。

总共限时为2.5h,完成第一道题就花了2h,第2道题因此也没有完成了,遗憾+惭愧!

 

下面给出第一道题的解答。

 

题目如下:

 

Question:

Given an array with positive integers and another integer for example{7 2 4} 9, you are required to generate an equation, by inserting operator add ("+") and minus ("-") among the array . The left side of equation are consist of the array and the right side of equation is the integer. here the result is 7-2+4=9

 

Rules:

Don't include any space in the generated equation.
In case there is no way to create the equation, please output "Invalid". For example {1 1} 10, output is "Invalid"
The length of the integer array is from 1 to 15( include 1 and 15). If the length is 1, for example the input  {7} 7, the output is 7=7
There is no operator "+" or "-" in front of the first number:
Don't change the order of the numbers. For example:  {7 2 4}  9. 7-2+4=9 is correct answer, 4-2+7=9 is wrong answer.
There could be multiple input, meaning your function could be called multiple times. Do remember print a new line after the call. 

Sample Input and Output:

Input:

1 2 3 4 10

1 2 3 4 5

Output:

1+2+3+4=10

Invalid

---------------------------

 

#include "stdafx.h"
#include <iostream>
#include <cstring>

using namespace std;

/************************************************************************/
/**
 Args:
 array[]: the inputted array
 final: the target value
 length: the element length
*/

void createEquationAndPrint(int array[], int length, int final){
  //Your Code is here

  cout<<"Invalid";
 }



int splitAndConvert(char* strings,int array[]){
  char*tokenPtr = strtok(strings," ");
  int i=0;
  while(tokenPtr!=NULL){
  array[i] = atoi(tokenPtr);
  i++;
  tokenPtr=strtok(NULL," ");
 }
 return i;
}

int main(){
 char line[1000] = {0} ;
 while(gets(line)){
  int array[30] = {0};
  int length = splitAndConvert(line,array);
  if(length==0){
   break;
  }
  createEquationAndPrint(array, length-1, array[length-1]);
  cout<<endl;
 }
 return 0

 

很明显,题目要求填写函数createEquationAndPrint的具体实现过程。

 

分析:这道题,咋一看来,应该属于类似全排列的题型,一般需要用递归的思路来解决。但在线笔试不允许添加额外、单独的函数作为递归函数,所以最终放弃了该思路,采用循环才完成全排列的遍历。

 

我当时在线的函数设计如下:

 

void createEquationAndPrint(int array[], int length, int final){
    //Your Code is here
    if(!array || length<0)
        return;

    bool found = false;
    int i = 0;
    char *opera = new char[length+1];
    while(i<length+1)
    {
        opera[i++] = '+';
    }
    opera[length] = '=';
    int *array_bak = new int[length+1];
    i = 0;
    while(i<length+1)
    {
        array_bak[i] = array[i];
        i++;
    }
    
    int allSum = 0;
    i = 0;
    while(i<length)    //all number except the final one
    {
        allSum += array[i];
        i++;
    }

    if(allSum < final)
    {
        found = false;
        cout<<"Invalid";
    }
    else if(allSum == final)
    {
        found = true;

        i = 0;
        while(i<length)
        {
            opera[i] = '+';
            i++;
        }
        opera[length] = '=';

        cout << array_bak[0];
        i = 1;
        while(i<length+1)
            cout << opera[i] << array_bak[i++];
        //cout << endl;
    }
    else
    {
        int k = 1;
        while(k < length)
        {
            int currNum = array[k];

            if(currNum == 0)
            {
                k++;
                continue;
            }

            if(allSum-2*currNum < final)
            {
                k++;
                continue;
            }
            else if(allSum-2*currNum == final)
            {
                found = true;

                opera[k] = '-';

                cout << array_bak[0];
                int j = 1;
                while(j<length+1)
                    cout << opera[j] << array_bak[j++];
                //cout << endl;

                k++;
                continue;
            }
            else
            {
                allSum -= 2*currNum;
                array[k] = 0;
                opera[k] = '-';
                k = 0;
                continue;
            }
        }
    }

    delete opera;
    delete array_bak;

    if(found)
        return;
    else
        cout<<"Invalid";
}

 

 

本地测试时,尝试了多种不同的测试用例,没有发现问题,结果提交在线测试,各种问题,由于时间关系,没有来得及找到问题原因,匆匆提交~

后来笔试结束后,下来跟同学讨论了下,发现了当时在线设计的算法考虑不周全,存在很多问题,于是重新考虑本题的设计。

 

还是想使用递归来实现,主要在于代码可能会比较精简。但递归过程中,可能需要保存很多中间变量。之前看过的一些算法设计题,一般都是通过函数参数传递引用来保存,但这里已经限定了递归函数的形式,所以最终采用静态全局变量来进行解决。由于递归的过程也是一个压栈、出栈的操作过程,因此基于栈来保存中间变量也不是没有可能。这个思路暂时没有实现。

下面给出这种思路的解法:

 

 

 1 void createEquationAndPrint(int array[], int length, int final){
 2     //Your Code is here
 3     static int sum = 0;
 4     static bool found = false;
 5     static char *print_str = new char[31];
 6     static int origin_length = length;
 7     static int recur_times = 0;
 8 
 9     if(recur_times == 0)
10     {
11         sum = 0;
12         found = false;
13         origin_length = length;
14     }
15 
16     recur_times++;
17 
18     if(length == 1)        //if only one element
19     {
20         if(array[0] == final)
21         {
22             sprintf(print_str, "%d=%d", array[0], final);
23             found = true;
24             cout << print_str << endl;
25         }
26     }
27     else if(length > 2)        //when many elements for add/minor
28     {
29         if(length == origin_length)
30         {
31             sum = array[0];
32             sprintf(print_str, "%d", array[0]);
33         }
34 
35         int curr = array[origin_length-length+1];
36 
37         int temp_sum = sum;
38         char *temp_str = new char[31];
39         strcpy(temp_str, print_str);
40 
41         sum = temp_sum + curr;
42         sprintf(print_str, "%s+%d", temp_str, curr);
43         createEquationAndPrint(array, length-1, final);
44 
45         sum = temp_sum - curr;
46         sprintf(print_str, "%s-%d", temp_str, curr);
47         createEquationAndPrint(array, length-1, final);
48 
49         delete temp_str;
50     }
51     else if(length == 2)    //when only one element for add/minor
52     {
53         if(sum + array[origin_length-length+1] == final)
54         {
55             sprintf(print_str, "%s+%d=%d", print_str, array[origin_length-1], final);
56             found = true;
57             cout << print_str << endl;
58         }
59         else if(sum - array[origin_length-length+1] == final)
60         {
61             sprintf(print_str, "%s-%d=%d", print_str, array[origin_length-1], final);
62             found = true;
63             cout << print_str << endl;
64         }
65     }
66 
67     if(length == origin_length)
68     {
69         if(!found)
70             cout << "Invalid" << endl;
71 
72         recur_times = 0;
73     }
74 
75     return;
76 }

个人觉得,目前的实现应该没有什么漏洞了,但整体代码还是比较复杂,应该有更简洁的设计方式,期待大家的集体智慧~~

 

至于第2道题,题目如下:

 

 

Question:

There is a 5*5 matrix; the elements in this matrix are different integer from 0 to 24. The elements in this matrix are disordered. 0 is a special element. The upper element, under element, left element and right element of 0 can be exchanged with 0. Such exchange operations are named as ‘U’, ‘D’, ‘L’ and ‘R’.

Operation "U" means 0 exchanged with its upper element.

Operation "D" means 0 exchanged with its under element.

Operation "L" means 0 exchanged with its left element.

Operation "R" means 0 exchanged with its right element.

 

For example, the original matrix is

[20, 18, 7, 19, 10

24, 4, 15, 11, 9

13, 0, 22, 12, 14

23, 16, 1, 2, 5

21, 17, 8, 3, 6]

With the operation sequence “URRDDL”, the new matrix will be

[20, 18, 7, 19, 10

24, 15, 11, 12, 9

13, 4, 22, 2, 14

23, 16, 0, 1, 5

21, 17, 8, 3, 6]

Now, we know the original matrix, the matrix after the operations and all the operations made on the original matrix. Please provide the correct sequence for the operations.

The input will be the original matrix, the target matrix and an operation sequence with wrong order.

If there is a correct sequence for this input, then print the correct sequence. Otherwise, print “None”.

 

Rules and example:

The elements in the original matrix are different.
The elements in the original matrix are random ordered.
The max lenght of operatoins is 15.
If "0" is already on the boundary, it is not possible to do further movement. for example, if 0 is in the top row, then there is no more "U".
The input will be the original matrix, the target matrix and an operation sequence with wrong order.
The output will be a correct operation sequence.
In case there is no way to get the target matrix with the input operations, please output “None”
Don’t include any space in the generated operation sequence.
For examples, the original matrix is
Example 1:

[20, 18, 7, 19, 10

24, 4, 15, 11, 9

13, 0, 22, 12, 14

23, 16, 1, 2, 5

21, 17, 8, 3, 6]

The target matrix is

[20, 18, 7, 19, 10

24, 4, 0, 11, 9

13, 22, 15, 12, 14

23, 16, 1, 2, 5

21, 17, 8, 3, 6]

The input operation sequence is “UR”

The output operation sequence should be “RU”

Example 2:

[20, 18, 7, 19, 10

24, 4, 15, 11, 9

13, 0, 22, 12, 14

23, 16, 1, 2, 5

21, 17, 8, 3, 6]

The target matrix is

[20, 18, 7, 19, 10

24, 15, 11, 12, 9

13, 4, 22, 2, 14

23, 16, 0, 1, 5

21, 17, 8, 3, 6]

The input operation sequence is “RRLUDD”

The output operation sequence should be “URRDDL”

 

代码结构如下:

/* Enter your code here. Read input from STDIN. Print output to STDOUT */
#include <stdio.h>
#include <string.h>

void calculateTheRightSequence(int originalMatrix[][5], int newMatrix[][5], 
                               char inputSequence[], char outputSequence[]);

int Getnput( char operation[], int originalMatrix[][5], int newMatrix[][5]);
int main()
{
    int original[5][5];
    int newMatrix[5][5];
    char inputOperation[100]={0};
    char outputOperation[100]= {0};
    while( Getnput(inputOperation, original, newMatrix) )
    {
        calculateTheRightSequence(original, newMatrix, inputOperation, outputOperation);
        printf("%s\n", outputOperation);
    }
    return 0;
}

//your code is here
void calculateTheRightSequence(int originalMatrix[][5], int newMatrix[][5], 
                               char inputSequence[], char outputSequence[])
{
}

int Getnput( char operation[], int originalMatrix[][5], int newMatrix[][5])
{
    int i = 0, j = 0;
    for( i = 0; i < 5; ++i )
        for(j = 0; j < 5; ++j)
    {
        if( scanf(" %d ", &originalMatrix[i][j]) != 1 )
            break;
    }
    if( j < 5 ) return 0;
    for( i = 0; i < 5; ++i )
        for(j = 0; j < 5; ++j)
    {
        scanf(" %d ", &newMatrix[i][j]);
    }
    
    scanf( "%s ", operation );  
    return 1;
}

应该也是个类似全排列问题,留待后面慢慢考虑,也算是贴出来跟大伙分享,哈哈~

 

2012-09-25第二次在线笔试

 

 

Question 1 / 2.
Given an array A, find the maximum neighboring-peak-valley difference of A,  MaxD(A).

For example, A={2, 3, 6, 5, 7, 9}, the elements 2, 5 could be regarded as the valley while 6 and 9 are the peaks. The difference of each neighboring peak-valley pair could be enumerated as below:
D[2, 6]=4, D[6,5]=1, D=[5,9]=4.
Thus, MaxD(A)=4.

Please write a program to find the maximum neighboring-peak-valley difference of an array. The input contains several lines(10 lines at most), and each line contains of several numbers separated by space. We treat every line an array.And each line has 2 numbers at least and 20 numbers at most.

The output should be the maximum neighboring-peak-valley difference of the arrays and separated by comma. For example:

Input:
2 3 6 5 7 9
2 3 6 5 7
2 3 6 5 7 9 10

Output:
4,4,5

 

思路:本题比较简单,考虑好边界情况就可以了

 

#include "stdafx.h"
#include <stdio.h>
#include <string.h>

#define ISSPACE(x) ((x)==' '||(x)=='\r'||(x)=='\n'||(x)=='\f'||(x)=='\b'||(x)=='\t')

char * rightTrim(char *str){
    int len = strlen(str);
    while(--len>=0){
        if(ISSPACE(str[len])){
            str[len] = '\0';
        }else{
            break;
        }
    }
    return str;
}

char * getInputLine(char *buffer, int length){
    if(fgets(buffer,length, stdin)==NULL){
        return NULL;
    }
    rightTrim(buffer);
    if(strlen(buffer)<=0){
        return NULL;
    }
    return buffer;
}

/*
For example, A={2, 3, 6, 5, 7, 9}, the elements 2, 5 could be regarded as the valley while 6 and 9 are the peaks. 
The difference of each neighboring peak-valley pair could be enumerated as below:
D[2, 6]=4, D[6,5]=1, D=[5,9]=4.
Thus, MaxD(A)=4.
*/

void maxNeighboringPeak(char ** data, int count){
    /* Enter your code here. Read input from STDIN. Print output to STDOUT */
    int *MaxD = new int[count];
    char *line_char = NULL;
    int line_int[20];
    int peak_valley_value[20];
    int peak_valley_label[20];

    for(int i=0; i<count; i++)
    {
        line_char = data[i];
        int line_len = strlen(line_char);

        int num = 0;
        int begin, end;
        begin = 0;
        end = 0;
        for(int j=0; j<line_len; j++)
        {
            int temp_num = 0;

            if(line_char[j] == ' ')
                end = j-1;
            else
            {
                if(j==line_len-1)
                    end = j;
                else
                    continue;
            }

            for(int k=begin; k<=end; k++)
            {
                temp_num = 10*temp_num + (line_char[k]-'0');
            }

            line_int[num] = temp_num;
            num++;

            begin = end+2;
        }

        int peak_valley_num = 0;
        for(int j=0; j<num; j++)
        {
            if(j==0)
            {
                if(line_int[j] < line_int[j+1])
                {
                    peak_valley_value[peak_valley_num] = line_int[j];
                    peak_valley_label[peak_valley_num] = -1;
                    peak_valley_num++;
                }
                else if(line_int[j] > line_int[j+1])
                {
                    peak_valley_value[peak_valley_num] = line_int[j];
                    peak_valley_label[peak_valley_num] = 1;
                    peak_valley_num++;
                }
            }
            else if(j==num-1)
            {
                if(line_int[j-1] < line_int[j])
                {
                    peak_valley_value[peak_valley_num] = line_int[j];
                    peak_valley_label[peak_valley_num] = 1;
                    peak_valley_num++;
                }
                else if(line_int[j-1] > line_int[j])
                {
                    peak_valley_value[peak_valley_num] = line_int[j];
                    peak_valley_label[peak_valley_num] = -1;
                    peak_valley_num++;
                }
            }
            else
            {
                if(line_int[j-1] <= line_int[j] && line_int[j] >= line_int[j+1])
                {
                    peak_valley_value[peak_valley_num] = line_int[j];
                    peak_valley_label[peak_valley_num] = 1;
                    peak_valley_num++;
                }
                else if(line_int[j-1] >= line_int[j] && line_int[j] <= line_int[j+1])
                {
                    peak_valley_value[peak_valley_num] = line_int[j];
                    peak_valley_label[peak_valley_num] = -1;
                    peak_valley_num++;
                }
            }
        }

        MaxD[i] = 0;
        for(int j=0; j<peak_valley_num-1; j++)
        {
            int temp;
            if(peak_valley_label[j] + peak_valley_label[j+1] == 0)
                temp = (peak_valley_value[j] > peak_valley_value[j+1]) ? (peak_valley_value[j] - peak_valley_value[j+1]) : (peak_valley_value[j+1] - peak_valley_value[j]);
            MaxD[i] = (MaxD[i] > temp ? MaxD[i] : temp);
        }
    }

    for(int j=0; j<count; j++)
    {
        if(j==0)
            printf("%d", MaxD[j]);
        else
            printf(",%d", MaxD[j]);
    }

    delete MaxD;
}


int main(int argc, char ** argv){
    char buffers[512][512];
    char *input[512];
    int inputCount = 0;

    while(getInputLine(buffers[inputCount], 512) != NULL){
        input[inputCount++] = buffers[inputCount];
    }

    maxNeighboringPeak(input, inputCount);
    return 0;
}

 

 

Question 2 / 2.
We have a file which contains lines of some classify rules, we can place integers ( 0 < n < max(Integer)) to different categories by the rules, for example:

n1 : a = 4
n2 : a = 1 or a = 2 or a = 23
n3 : a > 100
n4 : a > 24 and a < 54
n5 : a > 54 and a < 58 or a = 22

The first line means if a number equals to 4, then it should be place to category n1;
The second line means if a number equals to 1 or 2 or 23, then it should be place to category n2;
The third line means any number greater than 100 should be placed into category n3;
The fourth line means any number greater than 24 and smaller than 24 should be placed into category n4;
The fifth line means any number greater than 54 and smaller than 58 or equals to 22 should be placed into category n5.

The file has the following rule

1. Category and rules are sperated by semicolon;
2. "a" is a key words in the file, it represent the integer;
3. Key words(":", "=", "or", ">", "<", "and", "a") are sperated by space;
4. "and" should have a higher precedence then "or", this meas rule "a > 10 or a > 5 and a < 8" will get true if a = 11


Write a program to parse a rule file and output the given number's category. If it's not belongs to any of the category, output "none". Please notice that expression evaluation API(eval() function or other equivalent functions) should not be used.

In all the testcases, we have a input like the following(The fist line contains several numbers we want to classify, and the category name can be any string):
45,22
n1 : a = 4
category 2 : a = 1 or a = 2 or a = 23
n3 : a > 100
n4 : a > 24 and a < 54
n5 : a > 54 and a < 58 or a = 22

And the output should be:
n4,n5

Information may be help:

1. The rules in the same testcase we provide are not conflict with anyone else;
2. None of the rule we provided is a self-conflict rule, for example, we provide no rule like this "n1 : a = 5 and a = 3".

 

思路:本题思路不难,难就 难在字符串库string.h中各种字符串操作,比较复杂,时间不够,就没做出来。。。

有兴趣的可以研究研究

 

#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define ISSPACE(x) ((x)==' '||(x)=='\r'||(x)=='\n'||(x)=='\f'||(x)=='\b'||(x)=='\t')

char * rightTrim(char *str)
{
    int len = strlen(str);
    while(--len>=0) {
        if(ISSPACE(str[len])) {
            str[len] = '\0';
        } else {
            break;
        }
    }
    return str;
}

char * getInputLine(char *buffer, int length)
{
    if(fgets(buffer,length, stdin)==NULL) {
        return NULL;
    }
    rightTrim(buffer);
    if(strlen(buffer)<=0) {
        return NULL;
    }
    return buffer;
}

int extractNumbersToArray(char *str, int *numbers)
{
    const char *split = ",";
    char *p = strtok (str,split);
    int index = 0;
    while(p!=NULL) {
        numbers[index++] = atoi(p);
        p = strtok(NULL,split);
    }
    return index;
}

void determineRuleAndOutput(int *numbers, int numberCount, char ** rules, int ruleCount)
{
    //your code here
    int curr_num = 0;
    char * curr_rule = NULL;
    for(int i=0; i<numberCount; i++)
    {
        curr_num = numbers[i];

        for(int j=0; j<ruleCount; j++)
        {
            curr_rule = rules[j];

            for(int k=0; k<strlen(curr_rule); k++)
            {

            }
        }
    }
}

int main(int argc, char ** argv)
{
    int numbers[1024];
    char numberBuffer[1024];
    getInputLine(numberBuffer, 1024);
    int numberCount = extractNumbersToArray(numberBuffer, numbers);
    char buffers[1024][1024];
    char *rules[1024];
    int ruleCount = 0;
    while(getInputLine(buffers[ruleCount], 1024) != NULL) {
        rules[ruleCount++] = buffers[ruleCount];
    }
    determineRules(numbers, numberCount, rules, ruleCount);
    return 0;
}

 

posted on 2012-09-20 16:10  风程  阅读(7214)  评论(11编辑  收藏  举报

导航