非平凡Java数学练习
我被问到这个问题是为了测试我的编程能力。虽然我觉得这和编程一样重要。我真的失败了,但我想知道是怎么做的,以供将来参考 理想的答案是使用递归和线程 你侄女的生日礼物是一套积木,她决定用3英寸×1英寸和4.5英寸×1英寸的积木做一块嵌板。对于结构完整性,块之间的空间不得在相邻行中对齐。例如,下面的13.5“×3”面板是不可接受的,因为前两行中的块之间的一些空间如虚线所示排列在一起 有2种方法可以构建7.5英寸×1英寸面板,2种方法可以构建7.5英寸×2英寸面板,4种方法可以构建12英寸×3英寸面板,7958种方法可以构建27英寸×5英寸面板。你侄女有多少种不同的方法来制作一个48英寸×10英寸的面板?答案将符合64位整数。写一个程序来计算答案非平凡Java数学练习,java,multithreading,math,recursion,geometry,Java,Multithreading,Math,Recursion,Geometry,我被问到这个问题是为了测试我的编程能力。虽然我觉得这和编程一样重要。我真的失败了,但我想知道是怎么做的,以供将来参考 理想的答案是使用递归和线程 你侄女的生日礼物是一套积木,她决定用3英寸×1英寸和4.5英寸×1英寸的积木做一块嵌板。对于结构完整性,块之间的空间不得在相邻行中对齐。例如,下面的13.5“×3”面板是不可接受的,因为前两行中的块之间的一些空间如虚线所示排列在一起 有2种方法可以构建7.5英寸×1英寸面板,2种方法可以构建7.5英寸×2英寸面板,4种方法可以构建12英寸×3英寸面板,
这就是问题所在,我不知道从哪里开始学习数学。我知道我需要为第一行计算所有可能的组合。但我真的不知道怎么做。然后,您可以在特定线程上计算下一行的所有可能组合,以此类推。然后,每个第一行组合都可以获得自己的线程,并将其设置传递到递归算法中,该算法将当前行与最后一行进行比较,并找到可能的答案。但我不能真正编程,因为我不知道如何计算任何行的可能组合。如果我这样做了,那么也许我可以检查一下这是否是合法的一行,没有两个街区正好在彼此的顶部错开,然后移到下一个街区。可能每一行都是一个for循环,在代码方面围绕下一行嵌套。但再一次,我不知道在数学方面该怎么做 我认为你对这个问题有了很好的初步理解。如果我正确理解了你的想法,你应该在每个块的位置上递归,而不是在每个行的位置上-因为垂直方向的块将很快排除任何普通行 下面是我将采用的方法:您最终将在内存中显式或隐式地构建一棵树:树可以是在递归函数中传递的参数。树的节点将是树的状态-因此根没有放置块。你放第一个街区,我们会到达那里,那代表一个新的状态 目标是构造一组叶节点,这些叶节点在填充板时都是完整的,并且没有裂缝。那我们怎么去呢 对于每个块的放置,有4种替代现实:水平放置的3x1块、垂直放置的3x1块(称为1x3)、水平放置的4.5x1块和1x4.5块。对于这些选项中的每一个,您都将尝试合法地将块放置在行中的下一点。如果沿着块的线条进行的某些操作不与板边缘重叠,块不共享垂直边缘是合法的,那么您可以接受该板作为中间状态,并使用该新状态递归。如果它不合法,那么这个国家就必须被放弃 按照这种方式,前4个子节点将是左下角的一个块,如[3x1、1x3、4.5x1、1x4.5]。这四种状态中的每一种在四种配置中的一种配置的右侧都有一个块,依此类推 为了跨行移动,当你点击右边缘时,我会找到最低的空格,并在它们从左到右对齐时任意填充。当边缘参差不齐时,这足以修剪大型集合,但在级别平坦时(如刚开始时)仍然可以很好地进行修剪 本质上,对于每个中间状态,树最多有4个节点,边表示尝试的放置。如果无法合法地将块放置在该尝试放置的位置,则不会递归、修剪该可能性以及树的所有后代
这种蛮力方法应该可以得到一个完整的电路板,即使它的计算复杂度是天文数字。只有在这一点上,您才能正确地解决一些应该考虑与线程并行化的问题。递归问题往往很适合线程,因为每个递归通常可以并行化,而不会带来太多麻烦。请确保你先把它弄好。这篇文章已经有将近5年的历史了,但也许我的答案对某些人有用。下面有两种解决方案。首先是没有多线程。第二个使用四个线程来解决问题。它计算48x4面板48x10的持续时间很长,但可以通过更改初始值轻松修改: nbOfRows、nbOfCols、墙宽和墙宽 无多线程的解决方案:
import java.io.*;
import java.util.*;
class WallFlexOld
{
static final float blocks[] = {3.0f, 4.5f};
static final int nbOfRows = 4;
static final int nbOfCols = 16;
static final float wallWidth = 48.0f;
static final float wall[][] = {
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
};
static long nbOfCombinations = 0;
public static void main(String args[])
{
long startTime = System.currentTimeMillis();
addBlock(0, 0);
long workingTime = System.currentTimeMillis() - startTime;
System.out.println("Working time: " + workingTime + "ms");
System.out.println("noc: " + nbOfCombinations);
}
static void addBlock(int row, int col)
{
for(float b: blocks)
{
wall[row][col] = b;
if(blockFit(row, col))
{
if(rowWidth(row) <= wallWidth)
{
if(rowWidth(row) == wallWidth)
{
if(row == (nbOfRows - 1))
nbOfCombinations++;
else
addBlock(row + 1, 0);
}
else //rowWidth < wallWidth
addBlock(row, col + 1);
}
}
wall[row][col] = 0;
}
}
static float rowWidth(int row)
{
float width = 0;
for(float b: wall[row])
width = width + b;
return width;
}
static boolean blockFit(int row, int col)
{
if(row == 0)
return true;
boolean fit = true;
float currentLenght = 0;
for(int i = 0; i < col; i++)
currentLenght = currentLenght + wall[row][i];
float lowerRowCurLenght = 0;
for(float b: wall[row - 1])
{
lowerRowCurLenght = lowerRowCurLenght + b;
if((currentLenght == lowerRowCurLenght) & (currentLenght != wallWidth))
fit = false;
}
return fit;
}
}
import java.io.*;
import java.util.*;
class Wall implements Runnable
{
private float blocks[];
private int nbOfRows;
private int nbOfCols;
private float wallWidth;
private float wall[][];
private long nbOfCombinations = 0;
private int row, col;
public long getNbOfCombinations() { return this.nbOfCombinations; }
Wall(float blocks[], int nbOfRows, int nbOfCols, float wallWidth, float wall[][], int row, int col)
{
this.blocks = blocks;
this.nbOfRows = nbOfRows;
this.nbOfCols = nbOfCols;
this.wallWidth = wallWidth;
this.wall = wall;
this.row = row;
this.col = col;
}
private boolean blockFit(int row, int col)
{
if(row == 0)
return true;
boolean fit = true;
float currentLenght = 0;
for(int i = 0; i < col; i++)
currentLenght = currentLenght + wall[row][i];
float lowerRowCurLenght = 0;
for(float b: wall[row - 1])
{
lowerRowCurLenght = lowerRowCurLenght + b;
if((currentLenght == lowerRowCurLenght) & (currentLenght != wallWidth))
fit = false;
}
return fit;
}
private float rowWidth(int row)
{
float width = 0;
for(float b: wall[row])
width = width + b;
return width;
}
private void addBlock(int row, int col)
{
for(float b: blocks)
{
wall[row][col] = b;
if(blockFit(row, col))
{
if(rowWidth(row) <= wallWidth)
{
if(rowWidth(row) == wallWidth)
{
if(row == (nbOfRows - 1))
nbOfCombinations++;
else
addBlock(row + 1, 0);
}
else //rowWidth < wallWidth
{
addBlock(row, col + 1);
}
}
}
wall[row][col] = 0;
}
}
@Override
public void run()
{
addBlock(row, col);
}
}
class WallMT
{
static final float blocks[] = {3.0f, 4.5f};
static final int nbOfRows = 4;
static final int nbOfCols = 16;
static final float wallWidth = 48.0f;
static final float wall[][] = {
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
};
public static void main(String args[])
{
wall[0][0] = blocks[0];
wall[0][1] = blocks[0];
Wall myWall1 = new Wall(blocks, nbOfRows, nbOfCols, wallWidth, getWallCopy(wall), 0, 2);
Thread t1 = new Thread(myWall1);
wall[0][0] = blocks[0];
wall[0][1] = blocks[1];
Wall myWall2 = new Wall(blocks, nbOfRows, nbOfCols, wallWidth, getWallCopy(wall), 0, 2);
Thread t2 = new Thread(myWall2);
wall[0][0] = blocks[1];
wall[0][1] = blocks[0];
Wall myWall3 = new Wall(blocks, nbOfRows, nbOfCols, wallWidth, getWallCopy(wall), 0, 2);
Thread t3 = new Thread(myWall3);
wall[0][0] = blocks[1];
wall[0][1] = blocks[1];
Wall myWall4 = new Wall(blocks, nbOfRows, nbOfCols, wallWidth, getWallCopy(wall), 0, 2);
Thread t4 = new Thread(myWall4);
long startTime = System.currentTimeMillis();
t1.start();
t2.start();
t3.start();
t4.start();
try
{
t1.join();
t2.join();
t3.join();
t4.join();
}
catch(InterruptedException ie)
{
System.out.println("Thread " + t1 + " interrupted.");
}
long workingTime = System.currentTimeMillis() - startTime;
System.out.println("Working time: " + workingTime + "ms");
System.out.println("noc: " + (myWall1.getNbOfCombinations() + myWall2.getNbOfCombinations() + myWall3.getNbOfCombinations() + myWall4.getNbOfCombinations()));
}
static private float[][] getWallCopy(float wall[][])
{
float tmpWall[][] = new float[nbOfRows][nbOfCols];
for(int i = 0; i < nbOfRows; i++)
for(int j = 0; j < nbOfCols; j++)
tmpWall[i][j] = wall[i][j];
return tmpWall;
}
}
多线程解决方案:
import java.io.*;
import java.util.*;
class WallFlexOld
{
static final float blocks[] = {3.0f, 4.5f};
static final int nbOfRows = 4;
static final int nbOfCols = 16;
static final float wallWidth = 48.0f;
static final float wall[][] = {
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
};
static long nbOfCombinations = 0;
public static void main(String args[])
{
long startTime = System.currentTimeMillis();
addBlock(0, 0);
long workingTime = System.currentTimeMillis() - startTime;
System.out.println("Working time: " + workingTime + "ms");
System.out.println("noc: " + nbOfCombinations);
}
static void addBlock(int row, int col)
{
for(float b: blocks)
{
wall[row][col] = b;
if(blockFit(row, col))
{
if(rowWidth(row) <= wallWidth)
{
if(rowWidth(row) == wallWidth)
{
if(row == (nbOfRows - 1))
nbOfCombinations++;
else
addBlock(row + 1, 0);
}
else //rowWidth < wallWidth
addBlock(row, col + 1);
}
}
wall[row][col] = 0;
}
}
static float rowWidth(int row)
{
float width = 0;
for(float b: wall[row])
width = width + b;
return width;
}
static boolean blockFit(int row, int col)
{
if(row == 0)
return true;
boolean fit = true;
float currentLenght = 0;
for(int i = 0; i < col; i++)
currentLenght = currentLenght + wall[row][i];
float lowerRowCurLenght = 0;
for(float b: wall[row - 1])
{
lowerRowCurLenght = lowerRowCurLenght + b;
if((currentLenght == lowerRowCurLenght) & (currentLenght != wallWidth))
fit = false;
}
return fit;
}
}
import java.io.*;
import java.util.*;
class Wall implements Runnable
{
private float blocks[];
private int nbOfRows;
private int nbOfCols;
private float wallWidth;
private float wall[][];
private long nbOfCombinations = 0;
private int row, col;
public long getNbOfCombinations() { return this.nbOfCombinations; }
Wall(float blocks[], int nbOfRows, int nbOfCols, float wallWidth, float wall[][], int row, int col)
{
this.blocks = blocks;
this.nbOfRows = nbOfRows;
this.nbOfCols = nbOfCols;
this.wallWidth = wallWidth;
this.wall = wall;
this.row = row;
this.col = col;
}
private boolean blockFit(int row, int col)
{
if(row == 0)
return true;
boolean fit = true;
float currentLenght = 0;
for(int i = 0; i < col; i++)
currentLenght = currentLenght + wall[row][i];
float lowerRowCurLenght = 0;
for(float b: wall[row - 1])
{
lowerRowCurLenght = lowerRowCurLenght + b;
if((currentLenght == lowerRowCurLenght) & (currentLenght != wallWidth))
fit = false;
}
return fit;
}
private float rowWidth(int row)
{
float width = 0;
for(float b: wall[row])
width = width + b;
return width;
}
private void addBlock(int row, int col)
{
for(float b: blocks)
{
wall[row][col] = b;
if(blockFit(row, col))
{
if(rowWidth(row) <= wallWidth)
{
if(rowWidth(row) == wallWidth)
{
if(row == (nbOfRows - 1))
nbOfCombinations++;
else
addBlock(row + 1, 0);
}
else //rowWidth < wallWidth
{
addBlock(row, col + 1);
}
}
}
wall[row][col] = 0;
}
}
@Override
public void run()
{
addBlock(row, col);
}
}
class WallMT
{
static final float blocks[] = {3.0f, 4.5f};
static final int nbOfRows = 4;
static final int nbOfCols = 16;
static final float wallWidth = 48.0f;
static final float wall[][] = {
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
};
public static void main(String args[])
{
wall[0][0] = blocks[0];
wall[0][1] = blocks[0];
Wall myWall1 = new Wall(blocks, nbOfRows, nbOfCols, wallWidth, getWallCopy(wall), 0, 2);
Thread t1 = new Thread(myWall1);
wall[0][0] = blocks[0];
wall[0][1] = blocks[1];
Wall myWall2 = new Wall(blocks, nbOfRows, nbOfCols, wallWidth, getWallCopy(wall), 0, 2);
Thread t2 = new Thread(myWall2);
wall[0][0] = blocks[1];
wall[0][1] = blocks[0];
Wall myWall3 = new Wall(blocks, nbOfRows, nbOfCols, wallWidth, getWallCopy(wall), 0, 2);
Thread t3 = new Thread(myWall3);
wall[0][0] = blocks[1];
wall[0][1] = blocks[1];
Wall myWall4 = new Wall(blocks, nbOfRows, nbOfCols, wallWidth, getWallCopy(wall), 0, 2);
Thread t4 = new Thread(myWall4);
long startTime = System.currentTimeMillis();
t1.start();
t2.start();
t3.start();
t4.start();
try
{
t1.join();
t2.join();
t3.join();
t4.join();
}
catch(InterruptedException ie)
{
System.out.println("Thread " + t1 + " interrupted.");
}
long workingTime = System.currentTimeMillis() - startTime;
System.out.println("Working time: " + workingTime + "ms");
System.out.println("noc: " + (myWall1.getNbOfCombinations() + myWall2.getNbOfCombinations() + myWall3.getNbOfCombinations() + myWall4.getNbOfCombinations()));
}
static private float[][] getWallCopy(float wall[][])
{
float tmpWall[][] = new float[nbOfRows][nbOfCols];
for(int i = 0; i < nbOfRows; i++)
for(int j = 0; j < nbOfCols; j++)
tmpWall[i][j] = wall[i][j];
return tmpWall;
}
}
所以你试过什么了吗?我没有诚实地告诉我们你做了什么。