微软苏州校招1月3日在线编程题2——Disk Storage

题目2 : Disk Storage

时间限制:10000ms

单点时限:1000ms

内存限制:256MB

描述

Little Hi and Little Ho have a diskstorage. The storage's shape is a truncated cone(截头圆锥体) of height H. R+H is radius oftop circle and R is radius of base circle. 
Little Ho buys N disks today. Every disk is a cylinder of height 1. Little Howants to put these disk into the storage under below constraints:

1. Every disk is placed horizontally. Itsaxis must coincide with the axis of storage.
2. Every disk is either place on the bottom surface or on another disk.
3. Between two neighboring disks in the storage, the upper one's radius minusthe lower one's radius must be less than or equal to M.

Little Ho wants to know how many disks hecan put in the storage at most.

输入

Input contains only one testcase.
The first line contains 4 integers: N(1 <= N <= 100000), M, H, R(1 <=M, R, H <= 100000000).
The second line contains N integers, each number prepresenting the radius of adisk. Each radius is no more than 100000000.

输出

Output the maximum possible number of diskscan be put into the storage.

样例输入

5 1 10 3

1 3 4 5 10

样例输出

4


基本思想就是穷举和递归,因为每选出一个盘子就相当于在R+1,H-1的子空间里放剩下的盘子。

以下内容是我的C++实现,由于本人水平有限,代码肯定存在不合理的地方,欢迎读者能提出意见。


文件1:disk_storage.h

#ifndef _DISK_STORAGE_H_
#define _DISK_STORAGE_H_

class DISKS_CL
{
    public:
        DISKS_CL(int _iN);
        ~DISKS_CL();
        DISKS_CL(const DISKS_CL& _clDisks);
        DISKS_CL& operator=(const DISKS_CL& _clDisks);


        int GetDiskByIndex(int iIndex) const;//获取一个盘子的半径
        void DeleteDiskByIndex(int iIndex);//删除一个盘子的半径数据
        int GetDiskNum() const;//获取问题中盘子的总数
    private:
        int iN;//disk number
        int *piRadius;//all radius

        void Input();//输入所有盘子的半径数据
};

class STORAGE_CL
{
    public:
        STORAGE_CL();
        ~STORAGE_CL();


        void Input();//输入数据
        int GetDiskNum();//获取问题中盘子的总数
        int FindMax(DISKS_CL& clDisks);//找出满足条件的最大存放数目
        
    private:
        int iN;
        int iH;
        int iR;
        int iM;
        //递归函数
        int DoFind(int _iH, int _iR, int _iPreIndex, DISKS_CL clDisks);
};

#endif

文件2:disk_storage_main.cpp

#include <iostream>

#include "disk_storage.h"

using namespace std;

STORAGE_CL::STORAGE_CL():iN(0),iH(0),iR(0),iM(0)
{
	Input();
	return;
}
STORAGE_CL::~STORAGE_CL()
{
	return;
}
void STORAGE_CL::Input()
{
	cin>>iN>>iM>>iH>>iR;
	return;
}

int STORAGE_CL::GetDiskNum()
{
	return iN;
}

int STORAGE_CL::FindMax(DISKS_CL& clDisks)
{
	return DoFind(iR,iH,-1,clDisks);
}

int STORAGE_CL::DoFind(int _iR, int _iH, int _iPreIndex, DISKS_CL clDisks)
{
	int i;
	int iRadius;
	int iResult;
	int iRet;
	int iPreRadius;

	if (0 == _iH)//没有空间了
	{
		return 0;
	}

	if (-1 == _iPreIndex)//第一个盘子
	{
		iPreRadius = iRadius - iM;
	}
	else//以后的盘子
	{
		iPreRadius = clDisks.GetDiskByIndex(_iPreIndex);
		clDisks.DeleteDiskByIndex(_iPreIndex);
	}
	
	iResult = 0;
	for (i=0; i<iN; i++)//对所有盘子循环
	{
		iRadius = clDisks.GetDiskByIndex(i);
		if (0 == iRadius)//跳过之前处理过的盘子
		{
			continue;
		}
		
		if (iRadius <= _iR && iRadius-iPreRadius >= iM)//满足条件则试取出这个盘子
		{
			iRet = DoFind(_iR+1, _iH-1, i, clDisks);
			if (iRet >= iResult)//记录这次循环中的最大结果
			{
				iResult = iRet + 1;
			}
		}
	}
	return iResult;
}

DISKS_CL::DISKS_CL(int _iN)
{
	iN = _iN;
	piRadius = new int[iN];

	Input();
}
DISKS_CL::~DISKS_CL()
{
	if (NULL != piRadius)
	{
		delete piRadius;
	}
	return;
}
DISKS_CL::DISKS_CL(const DISKS_CL& _clDisks)
{
	int i;
	iN = _clDisks.GetDiskNum();
	piRadius = new int[iN];

	for (i=0; i<iN; i++)
	{
		piRadius[i] = _clDisks.GetDiskByIndex(i);
	}
	return;
}
DISKS_CL& DISKS_CL::operator=(const DISKS_CL& _clDisks)
{
	
	int i;
	iN = _clDisks.GetDiskNum();
	piRadius = new int[iN];
	for (i=0; i<iN; i++)
	{
		piRadius[i] = _clDisks.GetDiskByIndex(i);
	}
	return *this;
}

int DISKS_CL::GetDiskByIndex(int iIndex) const
{
	return piRadius[iIndex];
}
void DISKS_CL::DeleteDiskByIndex(int iIndex)
{
	piRadius[iIndex]=0;
	return;
}
int DISKS_CL::GetDiskNum() const
{
	return iN;
}


void DISKS_CL::Input()
{
	int i;
	for (i=0;i<iN;i++)
	{
		cin>>piRadius[i];
	}
	return;
}

int main()
{
	int iNum;
	STORAGE_CL clStorage;
	DISKS_CL clDisks(clStorage.GetDiskNum());
	iNum = clStorage.FindMax(clDisks);
	cout<<iNum<<endl;
	return 0;
}

运行结果:

hc@ubuntu:~/Workspace/ms_proj/src$ ./run_disk_storage 
5 1 10 3
1 3 4 5 10
4
hc@ubuntu:~/Workspace/ms_proj/src$ ./run_disk_storage 
6 2 10 3 
1 2 3 4 5 6  
3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值