求一个小游戏的算法

ritter0302 2012-07-20 09:05:17
在玩一个android上的益智游戏CrossMe,自己想用VC++编写来玩玩
我遇到的问题:
怎么判断数组中依次有a,b,c,d...(最多10个)个相邻的1
array[100]={0,0,0,1,1...1,x,x..x,1,1...1,0,0..0...}

其中0表示初始值,x表示可以确定这个位置一定不是1

举个例子
1)只需要一组a=3
array[5]={0,1,1,1,x} 满足 OK
array[5]={0,1,1,x,x} 这样虽不满足但不错,下一步我可以把0改成1,使满足
array[5]={x,1,1,x,x} 这样就要警报,怎么都不能满足了
array[5]={x,1,1,1,1} 这样就要警报,超过了,

2)只需要一组a=3,b=2
array[7]={0,1,1,1,0,1,1} 满足 OK
array[7]={0,1,1,1,x,1,1} 满足 OK
array[7]={1,1,1,0,x,1,1} 满足 OK
array[7]={1,1,1,0,0,1,1} 满足 OK
array[7]={1,1,1,0,1,1,x} 满足 OK

array[7]={0,0,0,0,1,1,x} 可以判读b=2已经满足了
array[7]={0,1,1,1,0,0,0} 可以判读a=3已经满足了

array[7]={0,1,1,1,0,0,x} 报警,无法放置b=2
array[7]={0,1,x,x,0,0,0} 报警,无法放置a=3
当然a,b,c,d...(最多10个)如果有相等的更复杂些

请教高手给出思路,如果能够给出C语言的算法更好。

谢谢。

...全文
210 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
antiMight 2012-07-24
  • 打赏
  • 举报
回复

我加入了一个约定,每个块从遇到1开始算起因此不会出现把x000x算作可能为111的情况,如果输入的1构不成需要的块数,则后面的状态都是STATE_NONE,若输入的1构成的块数大于要求的,则跳出,后面的可以额外处理为FAIL,未经过各种BUG测试,难免有问题,仅提供我的思路

enum STATE{
STATE_NONE,//空状态
STATE_OK, //可以转变为需要的
STATE_FAIL,//无法转变
STATE_PASS //已为需要的块
};

STATE state[4] = {0};

int oneBlockNums[] = {1,3,2,5};//PASS 需要的连续1块的分布

int oneBlockLength = 0; //连续的1的长度
int blockIndex = 0; //块索引
int oneInBlock = 0; //块中1个数
int zeroInBlock = 0; //块中0个数

int numArray[] = {2,0,1,0,2,1,1,0,0,1,1,1,2,0,1,1,1,0,2};//2代表x,不可能为1,所以需要在数组两段加上2
int arynum = sizeof(numArray)/sizeof(int);
int blocknum = sizeof(oneBlockNums)/sizeof(int);

bool processBegan = false; //此参数防止开头有很多x的情况
bool previousOne = false; //上一个数字为1
for(int i = 0; i < arynum; i++)
{
if(processBegan == false && numArray[i] != 2)
processBegan = true;
if(processBegan) {

if(blockIndex > blocknum - 1) //实际块数大于要求块数,退出循环,之后相当于都为FAIL
break;

if(numArray[i] == 1)
{
oneInBlock++;
oneBlockLength++;
previousOne = true;
}

else if(previousOne) //上一个数是1,当前不是1
{
if(oneBlockLength == oneBlockNums[blockIndex])
{
state[blockIndex] = STATE_PASS;
oneInBlock = 0; //若此块PASS,则进入下一块
zeroInBlock = 0;
blockIndex++;
}
else if(oneBlockLength > oneBlockNums[blockIndex])
{
state[blockIndex] = STATE_FAIL;//若此块FAIL,则进入下一块
oneInBlock = 0;
zeroInBlock = 0;
blockIndex++;
}

oneBlockLength = 0;
previousOne = false;
}

if(numArray[i] == 0)
{
if(oneInBlock + zeroInBlock >= oneBlockNums[blockIndex]) //足够满足该块,则进入下一块
{
state[blockIndex] = STATE_OK;
oneInBlock = 0;
zeroInBlock = 0;
blockIndex++;
}
zeroInBlock++;
}

else if(numArray[i] == 2)
{
if(state[blockIndex] != STATE_PASS)
{
if(oneInBlock != 0) { //防止xxxx时每次x都累加块

if(oneInBlock + zeroInBlock >= oneBlockNums[blockIndex]) //块内0个数加上1个数就是最大的可能数
{
state[blockIndex] = STATE_OK;
}
else
{
state[blockIndex] = STATE_FAIL;
}

blockIndex++;
}

oneInBlock = 0;
zeroInBlock = 0;
}
}
}
}

cout << state[0] <<" "<< state[1] <<" "<< state[2] <<" "<<state[3]<<endl;


丈八涯 2012-07-22
  • 打赏
  • 举报
回复
一个简单的方法:
设计一个结构:
struct linkNode
{
int m_iStartPos;//记录1的起始位置
int m_iLength;//记录连续1的长度
bool m_bLeftIsZero;//记录左侧是否为0
bool m_bRightIsZero;//记录右侧是否为0
}

这样遍历字符串之后就能得到依次的linkNode。然后进行判断即可。其中如果存在两个linkNode共用一个0的情况,那么如果这个0变为1则两个linkNode就会合并。

33,027

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧