一名男子正在保持足球(足球)比赛的得分。他跟踪这样的部分结果:1-0,1-1,2-1,2-2,3-2。所有这些部分结果中的目标总和为15,最终结果为3-2,即5个目标。给定N
这是部分结果的目标总和,您需要找到最终结果的目标数。以下是一些例子:
输入15
输出5输入6
输出3输入55
输出10
我无法使用循环来解决问题;我只能使用if / else和arithmetical操作。仅使用这些操作,我如何才能找到最终结果的目标数量?
答案 0 :(得分:2)
这是一个求和问题。每次进球时都会创建一条记录。记录总是比前一记录大一个。总数是所有记录的总和。
总计=总和(进球数)
总数是1,那么你知道目标的数量也是1。
如果总数为3则有两个进球(1和1 + 1)
55 = 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1所以有10个进球。
编辑计算实际答案比使用其他答案中显示的分数数学更简单,但它需要求解二次方程。
Note that the solution to ax**2 + bx + c == 0 is
x = (-b +/- SQRT( b**2 - 4*a*c) / 2*a
T = n(n+1)/2
2T = n**2 + n
n**2 + n - 2T = 0
n = (-1 +/- SQRT( 1 - 4*1*(-2T))) / (2 * 1), n > 0
n = (SQRT( 1 + 8T ) - 1) / 2
so if T = 10, n = (SQRT(81) - 1) / 2 == 4
答案 1 :(得分:1)
r ="result"
s = "sum of goals"
n = "number of goals"
r s n
1-0 1 1
1-1 3 2
2-1 6 3
2-2 10 4
3-2 15 5
这告诉我们s只是前n个整数的总和,但我们需要n(s),而不是s(n)。
这是一个示例计算。
以下是在java中实现此目的的代码:
class Example {
public static int n(int s) {
return (int) Math.round(-1.0 / 2.0 + Math.sqrt(1.0 / 4.0 + 2.0 * s));
}
public static int s(int n) {
return (n * (n + 1)) / 2;
}
public static void main(String[] args) {
for (int n = 0; n <= 10; n++) {
int s = s(n);
printResult(s);
}
}
private static void printResult(int s) {
int n = n(s);
System.out.println("If the sum of goals is " + s + ", then the number of goals is " + n);
}
}
这是输出:
If the sum of goals is 0, then the number of goals is 0
If the sum of goals is 1, then the number of goals is 1
If the sum of goals is 3, then the number of goals is 2
If the sum of goals is 6, then the number of goals is 3
If the sum of goals is 10, then the number of goals is 4
If the sum of goals is 15, then the number of goals is 5
If the sum of goals is 21, then the number of goals is 6
If the sum of goals is 28, then the number of goals is 7
If the sum of goals is 36, then the number of goals is 8
答案 2 :(得分:1)
关于是否允许平方根这个问题是不明确的,它是否严格算作算术运算?
如果我们假设它不被允许并且我们不能使用任何循环,我们可以使用Newton's method来给出答案的良好近似值。其他人指出,我们基本上试图找到三角数T(n)=n(n+1)/2
的倒数。如果我们得到一笔金额S
,请f(n)=n^2/2+n/2-S
我们要解决f(n)=0
。 Newton的方法是一种快速迭代方法,给出初始猜测x0我们可以使用
x1 = x0 - f(x) / df(x)
其中df(x)=x-1/2
是衍生物。如果我们这样做4次,我们会得到一个很好的解决方案。
public class InverseSqrt {
static float f(float x,float S) {
return x*x/2+x/2-S;
}
static float df(float x,float S) {
return x+0.5f;
}
static float newton(float sum) {
float x = sum/2; // first initial guess
// Apply Newton's method four time
x = x - f(x,sum) / df(x,sum);
x = x - f(x,sum) / df(x,sum);
x = x - f(x,sum) / df(x,sum);
x = x - f(x,sum) / df(x,sum);
return x;
}
public static void main(String[] args) {
int i=0;
int ires=0;
do { // loop through possible number of goals
++i;
float s = i * (i+1) * 0.5f; // calculate the total
float res = newton(s);
ires = (int) (res+0.5); // round to nearest integer
System.out.print("T("+i+")="+(int)s);
System.out.println("\tres="+ires+"\t("+res+")");
} while(ires==i); // break first time it fails
}
}
这很好,直到输入为351,输出为26.但是下一个输入378没有给出28而不是27个目标。
我们可以通过使用5步骤的牛顿方法来处理输出1176,输出为48,从而改善一些事情。调整初始猜测可以显着改善事情,使用n / 16的初始猜测,5步骤工作到输入42195输出290。
使用Fast inverse squareroot可以找到更好的解决方案。这可以在this answer之后的Java中实现。
static float Q_rsqrt( float x )
{
float xhalf = 0.5f*x;
int i = Float.floatToIntBits(x);
i = 0x5f3759df - (i>>1);
x = Float.intBitsToFloat(i);
x = x*(1.5f - xhalf*x*x);
return x;
}
然后我们的牛顿迭代方法
static float newton(float sum) {
float x = Q_rsqrt(1/sum);
x = x - f(x,sum) / df(x,sum);
x = x - f(x,sum) / df(x,sum);
x = x - f(x,sum) / df(x,sum);
return x;
}
只有3个迭代步骤。
这适用于输入1073720960输出46340.在计算总和之后,下一项后面会给出整数溢出,因此可以说它适用于所有合法的int值。
这可能不会被视为合法解决方案,因为它使用的floatToIntBits(x)
和intBitsToFloat(x)
并非真正用作算术运算。
答案 3 :(得分:0)
似乎给出了算术级数S(n)的和,你必须找到n。 使用简单的数学运算并从等式计算n:
S(n) = n * (n + 1) / 2