Leetcode 957.N天后的牢房
<center> Leetcode 957.N天后的牢房 </center>
8间牢房排成一排,每间牢房不是有人住就是空着。
每天,无论牢房是被占用或空置,都会根据以下规则进行更改:
如果一间牢房的两个相邻的房间都被占用或都是空的,那么该牢房就会被占用。
否则,它就会被空置。
(请注意,由于监狱中的牢房排成一行,所以行中的第一个和最后一个房间无法有两个相邻的房间。)
我们用以下方式描述监狱的当前状态:如果第 i 间牢房被占用,则 cell[i]==1,否则 cell[i]==0。
根据监狱的初始状态,在 N 天后返回监狱的状况(和上述 N 种变化)。
输入:
cells = [1,0,0,1,0,0,1,0], N = 1000000000
输出:
[0,0,1,1,1,1,1,0]
思路
总共有八间牢房,只有空或非空两种状态,共2^8 = 256状态
N则有1e9,显然存在相同的状态,那么只要找到循环节就可以了。
class Solution
{
public:
int hashTable1[300]; //记录这个状态是否出现过
int hashTable2[300]; //记录这个状态出现在第几天
vector<int> prisonAfterNDays(vector<int>& cells, int N)
{
int id = 0;
for(int i=0; i<cells.size(); i++)
{
if(cells[i])id += (1<<i);
}
hashTable1[id]=1;
hashTable2[id]=0;
int i=0,flag = 0;
while(N--)
{
vector<int>temp;
id = 0;
for(int j=0; j<cells.size(); j++)
{
if(j==0||j==cells.size()-1)
temp.push_back(0);
else
{
if(cells[j-1]==cells[j+1])
{
temp.push_back(1);
id += (1<<j);
}
else
temp.push_back(0);
}
}
cells = temp;
if(flag)continue;
if(flag==0&&hashTable1[id]) ///找到出现过的点
{
flag = 1;
int repetend = i+1 - hashTable2[id];
N%=repetend; ///去除循环
}
hashTable1[id]=1;
hashTable2[id]=i+1;
i++;
}
return cells;
}
};