ROSECODE 560
网格染色
Grid painting
原题的交互功能已停用;现存程序以代码文本保留。
设有一个网格,共 M 行和 N 列。格子从左上角的 0 到右下角的 MxN-1 依次编号。用下面的代码将一些格子随机涂成黄色:
uint8 grid[NROWS*NCOLS] = {0};
void FillGrid(const int NROWS, const int NCOLS, const int NCELLS)
{
int NCellsPainted = (NCELLS+1)>>1;
uint painted = 0;
uint32 seed = 10001;
while (painted < NCellsPainted)
{
seed = seed * 10001 + 1001;
uint rowcol = seed % NCELLS;
if (grid[rowcol] == 0)
{
grid[rowcol] = 1; // [row,col] painted
++painted;
}
}
}
例如,在 6x7 网格中生成 [0, 40) 范围内的随机数,将 20 个格子涂色:
let createMatrix = (m, n) => {
let [row, column] = [[], []],
rowColumn = m * n
for (let i = 0; i < rowColumn; i++) {
column.push(i)
if ((i+1) % n === 0) {
row.push(column)
column = []
}
}
return row
}
let setColorForEachElement = (matrix, nums) => {
let row = matrix.map(row => {
let column = row.map((column, key) => {
return { number: column, color: nums.indexOf(column) != -1?'yellow':'white' }
})
return column
})
return row
}
let generateNumbers = (m, n, s) =>
{
let grid = Array(m*n).fill(0);
let nums = [];
let NCells = s;
let NCellsPainted = (s+1)>>1;
let painted = 0;
let seed = 10001;
while (painted < NCellsPainted)
{
seed = seed * 10001 + 1001;
seed %= 4294967296;
let rowcol = seed % NCells;
if (grid[rowcol] == 0)
{
grid[rowcol] = 1;
nums.push(rowcol);
++painted;
}
}
return nums;
}
const matrix = createMatrix(6, 7)
const colorApi = setColorForEachElement(matrix, generateNumbers(6,7,40))
let table ='<font face="Courier New"><table>'
colorApi.forEach(row => {
table+= '<tr>'
row.forEach(column => table += `<td style='background: ${column.color};'>${column.number}<td>` )
table+='</tr>'
})
table+= '</table></font>'
let outputDiv = document.getElementById("ExampleGrid");
outputDiv.innerHTML = table;
请注意,某些单元格是连续绘制的(在同一行上,绘制单元格右侧或左侧的单元格或同一列上/下单元格也被绘制)。找出这些随机涂色格子中包含多于 1 个格子的连通块,并把每个连通块视为一个集合。对于示例,我们将有以下两组:
S1 = {0, 1, 2, 3, 4, 5, 7, 8, 11, 15}
S2 = {17, 23, 24, 25, 28, 29, 30}
S1 具有 10 元素,其总和为 56 和 S2 具有 7 元素,其总和为 176。
如果我们有一个 9991x1001 网格,通过生成 [0, 10000000) 范围内的随机整数来给 5000000 个格子涂色,我们会有多少个这样的集合?
元素个数最多的集合编号是多少?
元素之和最大的集合编号是多少?
请注意,集合按最小元素排序并相应编号。
答案格式:a,b,c,d,e,f,g 其中
a 是集合数
b 是元素个数最多的集合编号
c 是集合 Sb 的元素数量
d 是集合 Sb 的元素之和
e 是元素和最大的集合的集合号
f 是集合 Se 的元素数量
g 是集合 Se 的元素之和
示例:上面的 6x7 网格为 2,1,10,56,2,7,176。
[我的时间:<10s]