我正在解决一个问题: 用户输入3个树高度和树高限制。然后程序计算要删除的树的数量。
示例输入:
Tree1: 14
Tree2: 7
Tree3: 16
Tree limit: 11
示例输出:
Amount to remove: 8
这对我来说通常不会太糟糕,虽然我还是初学者,但问题是,我将在没有if语句的情况下计算它。我必须使用Modulus来计算。我花了很长时间研究和尝试不同的东西,但我似乎无法得到它?有任何想法吗?
答案 0 :(得分:5)
您正在寻找的表达方式是:
tree[i] % max % tree[i];
当tree[i]
大于max
时:
示例:16和11
16 % 11 = 5
5 % 16 = 5
但tree[i]
小于max
时:
示例:7和11
7 % 11 = 7
7 % 7 = 0
int main(void)
{
int tree[3] = {0};
int max = 0;
int cut = 0;
printf("Max Height: "),
scanf("%d", &max);
for(int i=0; i<3; ++i)
{
printf("Tree%d: ",i+1),
scanf("%d", &tree[i]);
}
for(int i=0; i<3; ++i)
{
cut += (tree[i] % max) % tree[i];
}
printf("Amount to remove: %d\n", cut);
getchar();
return 0;
}
2015年8月(距离原帖近2年),我决定重温这个问题,并提出一个通用的解决方案。
看起来有点工作,但完整的表达是:
int cut = (tree % max % tree) + !!(tree/max) * (tree/max - 1) * max;
<强>示例:强>
| Tree | Max | Expression | Answer |
| 4 | 11 | 0 + 0 * -1 * 11 | 0 |
| 47 | 11 | 3 + 1 * 3 * 11 | 36 |
注意:我的使用!! (double-not)几乎只是一个C / C ++构造。可能无法使用其他语言。
答案 1 :(得分:5)
以下是一般解决方案:
#include <stdio.h>
#define CUTAMOUNT(tr, lim) (tr - lim) * (((2 * tr) - ((2 * tr) % (tr + lim))) / (tr + lim - 1))
int main (int argc, char **argv) {
int tree1 = 14;
int tree2 = 7;
int tree3 = 16;
int limit = 11;
int cutamounttotal = 0;
cutamounttotal += CUTAMOUNT(tree1, limit);
cutamounttotal += CUTAMOUNT(tree2, limit);
cutamounttotal += CUTAMOUNT(tree3, limit);
printf("Amount to remove: %d\n", cutamounttotal);
return 0;
}
仅算术运算。诀窍是要理解%是唯一可以创建步骤的算术运算符。操作数必须适当调整大小,以确保步骤只发生在我们想要的地方,而不是其他地方。然后我们可以利用该步骤来提供所需的结果。
答案 2 :(得分:1)
你可以只使用绝对值函数(abs),除法,减法,加法。
Tree1: 14
Tree2: 7
Tree3: 16
Tree limit: 11
14-11=3 ----->3+abs(3)=6 ----------> 6/2 =3
7-11=-4 ----> -4 + abs(-4)=0 -------------> 0/2=0
16-11=5 -----> 5+abs(5)=10 ------------> 10/2 = 5
...
...
...
3+5 = 8 :D
上面的文字显示了如何将较小的值转换为零。因此,只有更大的值才具有附加效果。
如果你不能使用abs()那么你可以移动左移+右移组合以获得绝对值。 但这可能是未定义的行为。结果是为签名值的右移定义的实现。
答案 3 :(得分:1)
我对自己提出这么多想法感到有些失望,但话虽这么说,我还是会站出来对所有n > 0
表示没有通用解决方案。不使用if
语句,或者不使用其他类型的技巧来模拟一个。如果有人证明我错了,我会很乐意吃掉我的话。
对于每棵树,明显而正确的解决方案是:
cut = max(height - limit, 0);
相当于:
if ( height - limit > 0 ) {
cut = height - limit;
} else {
cut = 0;
}
或者:
if ( height > limit ) {
cut = height - limit;
} else {
cut = 0;
}
最简单的方法(除了使用max()
函数之外)在没有实际明确使用if
语句的情况下模拟它是:
cut = (height - limit) * (height > limit);
因为height > limit
会在适当的时间评估为1
或0
。
您也可以使用while
循环进行模拟:
cut = 0;
while ( height > limit ) {
cut = height - limit;
break;
}
使用三元运算符是声称不使用if
的最明显的方法。可能还有其他一些技巧搞乱,但故事是一样的。
可以修改这些方法中的任何一种来使用模运算符作为问题,但所有实现的方法都是使更简单的算法更复杂。
我怀疑abelenky的答案中的方法是正在寻找的方法,可能是问题的最佳整体解决方案,尽管这只适用于0 < n < 2 * limit
。
答案 4 :(得分:0)
假设您已经将3个树高中的数据读入数组:
int trees[3];
int limit = 11;
int i;
int cut = 0;
for (i = 0; i < 3; i++) {
int cut += trees[i] > limit
? (trees[i] / limit - 1) * limit + trees[i] % limit
: 0;
}
printf("Amount to remove: %d\n", cut);
答案 5 :(得分:0)
[编辑] - 树的所有值的解决方案,使用%运算符,但不使用三元运算符:
#include <stdio.h>
#define MAX 11
int modsum(int a, int b, int c) ;
int main()
{
int results;
results = modsum(25, 7, 16);
return 0;
}
int modsum(int a, int b, int c)
{
int i, suma, sumb, sumc;
i=0;
while(a > 2*MAX)
{
i++;
a -= MAX;
}
suma = (i*MAX)+(a%MAX%a);
i=0;
while(b > 2*MAX)
{
i++;
b -= MAX;
}
sumb = (i*MAX)+(b%MAX%b);
i=0;
while(c > 2*MAX)
{
i++;
c -= MAX;
}
sumc = (i*MAX)+(c%MAX%c);
return suma+sumb+sumc;
}
答案 6 :(得分:0)
假设您被允许使用*
,/
和>
,您可以这样做:
#include <stdio.h>
int main()
{
int trees[3] = {24, 7, 16};
int limit = 11;
int allowedRemainder = 0;
int mod = 0;
int modCount = 0;
int i;
for (i = 0; i < 3; ++i)
{
allowedRemainder = (trees[i] / limit) - 1;
mod = trees[i] % limit;
modCount += (allowedRemainder > 0) * (allowedRemainder * limit) +
(allowedRemainder >= 0) * mod;
printf("Loop %d: mod = %d\n", i, modCount);
}
printf("Amount to remove: %d\n", modCount);
return 0;
}
(allowedRemainder > 0) * (allowedRemainder * limit)
表示如果我们至少有limit
次允许,请将limit
的倍数添加到modCount
。
(allowedRemainder >= 0) * mod
表示如果我们有limit
以上,请将余数添加到modCount
。
答案 7 :(得分:0)
树高在数组中,因为我懒得制作3个变量 它根据要求使用模运算符。
#include <stdio.h>
int main(void)
{
int tree_h[]={14,7,16};
int limit=11;
int i;
int remove=0;
for(i=0;i<3;i++)
{
remove+=(tree_h[i]>limit)*(tree_h[i]%limit);
}
printf("Amount to remove: %d\n", remove);
return 0;
}