Java 如果NXM乘法表按顺序排列,中间的数字是多少?
如果我有一个大小为3x5的乘法表:Java 如果NXM乘法表按顺序排列,中间的数字是多少?,java,algorithm,binary-search,Java,Algorithm,Binary Search,如果我有一个大小为3x5的乘法表: 1 2 3 4 5 2 4 6 8 10 3 6 9 12 15 我把这些数字按顺序排列: 1 2 2 3 3 4 4 5 6 6 8 9 10 12 15 中间的数字是多少?在这种情况下,是5 N和M总是奇数,因此只能有一个答案 有没有快速的解决方案?我在O(nlognm) 这算是家庭作业,但我真的对这一项迷茫了。我提出了一些想法,但都有一些缺点: public class Table { public static void
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
我把这些数字按顺序排列:
1 2 2 3 3 4 4 5 6 6 8 9 10 12 15
中间的数字是多少?在这种情况下,是5
N
和M
总是奇数,因此只能有一个答案
有没有快速的解决方案?我在O(nlognm)
这算是家庭作业,但我真的对这一项迷茫了。我提出了一些想法,但都有一些缺点:
public class Table {
public static void main(String[] ar) {
Scanner scanner = new Scanner(System.in);
int w = scanner.nextInt();
int h = scanner.nextInt();
int[] s = new int[w * h + 1];
for (int i = 1; i <= w; i++)
for (int j = 1; j <= h; j++)
s[i * j] = s[i * j] + 1;
int sum = 0;
for (int i = 0; i < s.length; i++) {
sum += s[i];
if (sum >= s.length / 2) {
System.out.println(i);
break;
}
}
}
}
为了克服记忆的限制,我试着数一数每一个数字出现的次数,直到它们出现的中间一个。我注意到乘法表中每个数字出现的次数就是它们的因子数
不够快
有人能提出一些建议吗?我知道在建议的
O(nlognm)
解决方案中使用了二进制搜索
1您可以通过计算乘法表中有多少项小于该值来对该值进行二进制搜索
这需要在二进制搜索中进行log(NM)迭代,因此我们需要能够计算总复杂度为O(Nlog(NM))的计数,以O(N)为单位
这可以通过依次考虑每个乘法表来实现。例如,假设我们的测试值是8,我们考虑的是3倍表
小于8的值将分别为3*1和3*2。我们可以通过简单地将测试值8除以表3并向下舍入,即floor(8/3)=2来确定有多少个,因此3次表将给出2的计数 在第二种方法的基础上,您能找到每个数字的素因子分解并使用它来计算它在表中出现的次数吗?(注意:这只是我的想法,我还没有试过。)@ajb你是什么意思?例如,在一个6x6表中,数字6出现4次(1x6,2x3,3x2,6x1),但它的主要因子只有2和3。好吧,现在不相关了,因为我认为发布的答案是正确的。我的意思是,如果N的素因式分解是(p1^n1)*(p2^n2)*…*(pm^nm),那么N的除数是(1+n1)(1+n2)…(1+nm)。所以在6=2^1*3^1的情况下,除数的数目是(1+1)*(1+1)=4。谢谢,这看起来非常好。回家后我会试试这个:)“值小于10…”你可能是指“小于8”?在问题中添加了一个解决方案。
public class Table {
public static void main(String[] ar) {
Scanner scanner = new Scanner(System.in);
int w = scanner.nextInt();
int h = scanner.nextInt();
int sum = 0;
for (int i = 1; i <= w * h; i++) {
for (int j = 1; j <= Math.sqrt(i); j++) {
if (i % j == 0) {
int k = i / j;
if (k <= w && k != j) sum++;
if (k <= h && k != j) sum++;
if (k <= w && k <= h && k == j) sum++;
}
}
if (sum >= (w * h + 1) / 2) {
System.out.println(i);
break;
}
}
}
}
1 <= N <= 10^5
1 <= M <= 10^5
public class Kertotaulu {
public static void main(String[] ar) {
Scanner scanner = new Scanner(System.in);
long h = scanner.nextLong();
long w = scanner.nextLong();
long min = 1;
long max = w*h;
long mid = 0;
while (min <= max) {
mid = (min + max) / 2;
long sum = 0;
for (int i = 1; i <= h; i++) sum += Math.min(mid / i, w);
sum--;
if (sum < (w * h) / 2) min = mid + 1;
else if (sum > (w * h) / 2) max = mid - 1;
else break;
}
long sum = 0;
for (int i = 1; i <= h; i++) sum += Math.min((mid - 1) / i, w);
sum--;
if (sum == (w * h) / 2) System.out.println(mid - 1);
else System.out.println(mid);
}
}