2006Google大赛疑问

2006Google大赛疑问

bykangtian0

      北京时间2006-9-6 00:00:00~2006-9-7 00:00:00Google大赛的资格赛时间,我继上次参加做了炮灰之后,又一次投入2006年的炮灰之中。

 

      我的参赛房间是Qualification Set 1room16,这个应该和后面说到的赛题有关。没有经过算法的强化训练,还是直接选的750分题目,所以提交的机会都没有,就直接壮烈牺牲了LLL

 

      但是我为了挑战自己,最后还是把两个题目做了。疑问是:

1IMGroups2号测试用例:1000      Returns: 64肯定是错的,我的程序计算结果是24,并且我手动验证也确实如此;

2Bishops3号测试用例:

7

{

 "........",

 "......#.",

 "........",

 ".#......",

 "........",

 ".....#..",

 "........",

 "...#...."}

Returns: 5544

这个我只能怀疑是错的,因为无法手动验证。我写的程序超过5分钟后计算结果是8985544

 

两个题目各有一个测试用例通不过。

 

下面先写我的实现,然后再附上题目。

//by: kangtian0

//time: 2006-9-7

 

#include<stdio.h>

 

classIMGroups{

public:

    intoptimalTime(intN);

};

 

//This method is the same as Combination Explosion.

//The partition groups is the integer part of log2N(2 should be subscript. ==truncate( lgN/lg2 ) )

//组合爆炸方法,每次划分的组数是log以为底N的对数

intIMGroups::optimalTime(intN){

    if (N < 6)returnN;

 

    intmessage =N;

    intgroups = -1;

    while (message > 0) {

        ++groups;

        message >>= 1;

    }

 

    intnextmes =N / groups;

    if ( (N %groups) > 0 ) {

        ++nextmes;

    }

 

    return (groups +optimalTime(nextmes) );

}

 

intmain(intargc, char* argv[])

{

 

    IMGroupsim;

 

    printf("the least time is %d /n",im.optimalTime(5) );

    printf("the least time is %d /n",im.optimalTime(6) );

    printf("the least time is %d /n",im.optimalTime(1000) );

 

    return 0;

}

 

输出:

the least time is 5

the least time is 5

the least time is 24

 

1000的解如下:

1000

9 Groups

6 Groups

4 Groups

111(8 Groups)

 

 

112(1 Groups)

18(2)

 

19(4)

4(1)

5(3)

9 + 6 + 4 + 5 = 24

//by: kangtian0

//time: 2006-9-7

 

#include<math.h>

#include<vector>

usingnamespacestd;

 

classBishops{

public:

    intcount(intk,vector<string>board);

 

private:

    vector<string>chessBoard;

    structchess{

        intx,y;

    };

    vector<chess>place;//不想优化了,应该是可以使用二分查找优化一点点

 

    boolnoAttack(intx,int y); //此方格和前面放置的方格是否会相互攻击

    intgetCount(intk,int row, int column,size_tsize, int emptys); //很普通的递规方法

 

};

 

boolBishops::noAttack(intx,int y){

 

    size_tsize =place.size();

 

    for (size_ti = 0; i < size; ++i) {

        if ( ((y -place[i].y) == (x -place[i].x)) || ((y -place[i].y) == (place[i].x -x)) ){

             returnfalse;

        }

    }

 

    returntrue;

 

}

 

intBishops::getCount(intk,int row, int column,size_tsize, int emptys){

 

    inti = 0,j = 0;

    intcount = 0;

 

    if (k >emptys) return 0;

    if (k == 0)return 1;

 

    for (i =row; i < size; ++i){

        if (i > row ) //后面的行从第列开始尝试

             column = 0;

        for (j =column; j < size; ++j)

             if( (chessBoard[i][j] =='.') &&noAttack(i,j)){

                  size_tplacesize =place.size();

                  place.resize(placesize+1);

                  place[placesize].x =i;

                  place[placesize].y =j;

 

                  if ( (j ==size-1) && (i+1 <size) )

                      count +=getCount(k-1,i+1, 0,size, emptys-1);

                  else

                      count +=getCount(k-1,i,j+1, size, emptys-1);

 

                  place.resize(placesize);

             }

    }

 

    returncount;

 

}

 

intBishops::count(intk,vector<string>board){

 

    //initialize member

    chessBoard =board;

    place.reserve(k);

 

    size_tsize =board.size();

    intemptys = 0;

    size_ti = 0,j=0;

 

    for(i = 0;i < size; ++i)

        for (j = 0;j < size; ++j)

             if (board[i][j] =='.')

                  ++emptys;

 

    

    intcounted =getCount(k, 0, 0,size,emptys);

    place.clear();

 

    returncounted;

 

}

 

intmain(intargc, char* argv[])

{

    Bishopsbishop;

    intcount;

    vector<string>board;

 

    board.reserve(20);

 

    //0

    board.clear();

    board.push_back(".");

    count =bishop.count(1,board);

    printf("test case 0: the count is %d /n",count);

 

    //1

    board.clear();

    board.push_back("...");

    board.push_back(".##");

    board.push_back("...");

 

    count =bishop.count(1,board);

    printf("test case 1: the count is %d /n",count);

 

    //2

    board.clear();

    board.push_back("...");

    board.push_back("...");

    board.push_back("...");

 

    count =bishop.count(3,board);

    printf("test case 2: the count is %d /n",count);

 

    //4

    board.clear();

    board.push_back("...");

    board.push_back(".#.");

    board.push_back("...");

 

    count =bishop.count(4,board);

    printf("test case 4: the count is %d /n",count);

 

    //5

    board.clear();

    board.push_back("...");

    board.push_back("###");

    board.push_back("...");

 

    count =bishop.count(0,board);

    printf("test case 5: the count is %d /n",count);

 

    //6

    board.clear();

    board.push_back("....");

    board.push_back("....");

    board.push_back(".#..");

    board.push_back("...#");

 

    count =bishop.count(2,board);

    printf("test case 6: the count is %d /n",count);

 

    //3

    board.clear();

    board.push_back("........");

    board.push_back("......#.");

    board.push_back("........");

    board.push_back(".#......");

    board.push_back("........");

    board.push_back(".....#..");

    board.push_back("........");

    board.push_back("...#....");

 

    count =bishop.count(7,board);

    printf("test case 3: the count is %d /n",count);

 

    return 0;

}

 

输出:

test case 0: the count is 1

test case 1: the count is 7

test case 2: the count is 26

test case 4: the count is 8

test case 5: the count is 1

test case 6: the count is 71

test case 3: the count is 8985544

 

 

Google Code Jam 2006 –Qualification Set 1 -> Room16

250

Problem Statement

    

Alex has a lot of contacts in his Hyper Instant Messenger (HIM), and therefore, it takes some time to find the right contact. HIM supports Contact Groups, and each contact can be placed into a group. However, HIM's group support is rather limited. It allows for only one of the following two scenarios: 1) Multiple groups, but every contact belongs to a single group, or 2) All contacts exist only in a global contacts list (and no groups are created).

It takes Alex k seconds to find an entry in any list of k entries. If groups exist, HIM will first show a list of all the groups, and once a group is selected, a list of all contacts within that group will be displayed. If groups do not exist, HIM will simply show a single list containing all the contacts in the global list. For example, if Alex has 5 contacts in the global list, it will take 5 seconds to find any one of them. If Alex splits those contacts into two groups with 2 and 3 users each, it will first take him 2 seconds to find the right group, and then 2 or 3 seconds to find the right contact depending on which group he chooses.

You will be given an int N representing the total number of contacts. Arrange the contacts optimally (either in one global contacts list or in several groups) such that the maximal time needed to find a contact is minimized. Return this time.

Definition

    

Class:

IMGroups

Method:

optimalTime

Parameters:

int

Returns:

int

Method signature:

int optimalTime(int N)

(be sure your method is public)

    

 

Constraints

-

N will be between 1 and 1000000, inclusive.

Examples

0)

 

    

5

Returns: 5

The example from the problem statement.

1)

 

    

6

Returns: 5

Alex can arrange the contacts into 2 groups with 3 contacts each. The total time needed to find any contact will be 2 seconds to find the right group plus 3 seconds to find the right contact within that group.

2)

 

    

1000

Returns: 64

 

This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2003, TopCoder, Inc. All rights reserved.

 

750

Problem Statement

    

You are given a square chessboard, and you must determine the number of ways you can place k bishops on the board so that no two bishops attack each other. Some of the cells on the board are destroyed, and a bishop cannot be placed on a destroyed cell. Two bishops attack each other if they are located on the same diagonal (even if there are destroyed cells between them).

You will be given a String[] board which represents the chessboard. The jth character of the ith element of board represents the cell at row i, column j. A '.' denotes an empty cell, and a '#' denotes a destroyed cell. Return the last four digits of the number of ways you can place k bishops on the board so that no two bishops attack each other.

Definition

    

Class:

Bishops

Method:

count

Parameters:

int, String[]

Returns:

int

Method signature:

int count(int k, String[] board)

(be sure your method is public)

    

 

Constraints

-

k will be between 0 and 64, inclusive.

-

board will contain between 1 and 8 elements, inclusive.

-

Each element of board will contain exactly n characters, where n is the number of elements in board.

-

Each character of each element of board will be either '.' or '#'.

Examples

0)

 

    

1

{"."}

Returns: 1

 

1)

 

    

1

{

 "...",

 ".##",

 "..."}

Returns: 7

There are 7 free cells, and the bishop can be placed in any of those cells.

2)

 

    

3

{

 "...",

 "...",

 "..."}

Returns: 26

 

3)

 

    

7

{

 "........",

 "......#.",

 "........",

 ".#......",

 "........",

 ".....#..",

 "........",

 "...#...."}

Returns: 5544

 

4)

 

    

4

{

 "...",

 ".#.",

 "..."}

Returns: 8

There are two basic possible placements of 4 bishops:

BBB B.B

.#. B#B

.B. ...

and the rotations of these two placements.

5)

 

    

0

{

 "...",

 "###",

 "..."}

Returns: 1

There is exactly one way of placing 0 bishops.

6)

 

    

2

{

 "....",

 "....",

 ".#..",

 "...#"}

Returns: 71

 

This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2003, TopCoder, Inc. All rights reserved.

 

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值