来自维京码学校工程原理准备课程:
10个朋友围坐在桌子周围,决定玩新游戏。在其中,他们通过从1到100的数字来计算。第一个人说" 1",第二个人说" 2"等等...但有一些捕获:
每当数字可被7整除时,它们会切换方向。因此,第6个人会说" 6",第7个人会说" 7"然后第6个人会说" 8"。 只要数字可被11整除,它们就会跳过下一个人。
伪代码一个程序,它将确定哪个玩家是那个" 100"。 如何开始弄清楚这一个的逻辑?
答案 0 :(得分:0)
通常在编程中,选择合适的数据结构可以大大简化解决特定问题的算法。使用circular doubly-linked list可以优雅地解决您的问题。由于有十个朋友坐在一个圈子里,我们将它们放入链表如下:
next +-------+ next
+--------->| |----------+
| | 1 | |
| +--| |<--+ v
+-------+ | +-------+ | +-------+
| | | | | |
+-->| 10 |<--+ prev prev +--| 2 |---+
| | | | | |
next | +-------+ +-------+ | next
| | ^ v
+-------+ | prev prev | +-------+
| | | | | |
| 9 |<--+ +---| 3 |
| | | |
+-------+ +-------+
^ | ^ |
next | | prev prev | | next
| v | v
+-------+ +-------+
| | | |
| 8 |---+ +-->| 4 |
| | | | | |
+-------+ | prev prev | +-------+
^ v | |
next | +-------+ +-------+ | next
| | | | | |
+---| 7 |--+ prev prev +-->| 5 |<--+
| | | | | |
+-------+ | +-------+ | +-------+
^ +-->| |--+ |
| | 6 | |
+----------| |<---------+
next +-------+ next
例如,在JavaScript中,您可以将其编写为:
var firstFriend = toList([1,2,3,4,5,6,7,8,9,10]);
function Node(prev, data, next) {
this.prev = prev;
this.data = data;
this.next = next;
}
function toList(array) {
var length = array.length;
if (length === 0) throw new Error("empty array");
var root = new Node(null, array[0], null), node = root, i = 1;
while (i < length) node = node.next = new Node(node, array[i++], null);
return (root.prev = node).next = root;
}
现在,我们可以使用两个相互递归的函数解决问题:一个用于向前计数的朋友,另一个用于向反方向计数的朋友:
var answer = forward(1, firstFriend);
function forward(count, friend) {
if (count === 100) return friend.data;
if (count % 7 === 0 &&
count % 11 === 0) return reverse(count + 1, friend.prev.prev);
if (count % 7 === 0) return reverse(count + 1, friend.prev);
if (count % 11 === 0) return forward(count + 1, friend.next.next);
return forward(count + 1, friend.next);
}
function reverse(count, friend) {
if (count === 100) return friend.data;
if (count % 7 === 0 &&
count % 11 === 0) return forward(count + 1, friend.next.next);
if (count % 7 === 0) return forward(count + 1, friend.next);
if (count % 11 === 0) return reverse(count + 1, friend.prev.prev);
return reverse(count + 1, friend.prev);
}
总而言之,答案是1
:
var firstFriend = toList([1,2,3,4,5,6,7,8,9,10]);
var answer = forward(1, firstFriend);
alert(answer);
function Node(prev, data, next) {
this.prev = prev;
this.data = data;
this.next = next;
}
function toList(array) {
var length = array.length;
if (length === 0) throw new Error("empty array");
var root = new Node(null, array[0], null), node = root, i = 1;
while (i < length) node = node.next = new Node(node, array[i++], null);
return (root.prev = node).next = root;
}
function forward(count, friend) {
if (count === 100) return friend.data;
if (count % 7 === 0 &&
count % 11 === 0) return reverse(count + 1, friend.prev.prev);
if (count % 7 === 0) return reverse(count + 1, friend.prev);
if (count % 11 === 0) return forward(count + 1, friend.next.next);
return forward(count + 1, friend.next);
}
function reverse(count, friend) {
if (count === 100) return friend.data;
if (count % 7 === 0 &&
count % 11 === 0) return forward(count + 1, friend.next.next);
if (count % 7 === 0) return forward(count + 1, friend.next);
if (count % 11 === 0) return reverse(count + 1, friend.prev.prev);
return reverse(count + 1, friend.prev);
}
&#13;
手动解决以检查是否正确:
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
+=====+=====+=====+=====+=====+=====+=====+=====+=====+=====+
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | | | |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 12 | | 11 | 10 | 9 | 8 | | | | |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| | | | | | | | | 14 | 13 |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| | | | | | | | | | 15 |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 16 | 17 | 18 | 19 | 20 | 21 | | | | |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 25 | 24 | 23 | | 22 | | | | | |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| | | | | | | | 28 | 27 | 26 |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| | | | | | | | | 29 | 30 |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 31 | 32 | 33 | | 34 | 35 | | | | |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 40 | 39 | 38 | 37 | 36 | | | | | |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| | | | | | | | | 42 | 41 |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| | | | | | | | | | 43 |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 44 | | 45 | 46 | 47 | 48 | 49 | | | |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 55 | 54 | 53 | 52 | 51 | 50 | | | | |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| | | | | | | | | 56 | |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| | | | | | | | | | 57 |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 58 | 59 | 60 | 61 | 62 | 63 | | | | |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 67 | | 66 | 65 | 64 | | | | | |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| | | | | | | | 70 | 69 | 68 |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| | | | | | | | | 71 | 72 |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 73 | 74 | 75 | 76 | 77 | | | | | |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 80 | 79 | 78 | | | | | | | |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| | | | | | | 84 | 83 | 82 | 81 |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| | | | | | | | 85 | 86 | 87 |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 88 | | 89 | 90 | 91 | | | | | |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 95 | 94 | 93 | 92 | | | | | | |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| | | | | | | | 98 | 97 | 96 |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| | | | | | | | | 99 | |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 100 | | | | | | | | | |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
虽然这个解决方案是递归的,但每个递归程序都可以使用堆栈转换为非递归程序。这个程序的伪代码非常简单。因此,我会把它作为练习让你弄清楚。
答案 1 :(得分:-1)
我所做的是创建一个for循环到100,内部有一个跟踪方向的变量,另一个跟踪当前玩家。我在循环中使用if语句来决定是应该切换方向还是当前播放器递增或递减。
这是我最终的结果,它并不漂亮,但应该有效:
int curPlayer = 1;
int direction = 1;
for(int i = 1; i <= 100; i++)
{
if(i % 7 == 0 && direction == 1)
{
direction = 0;
}
else if(i % 7 == 0)
{
direction = 1;
}
if(i % 11 == 0 && direction == 1)
{
curPlayer++;
}
else if(i % 11 == 0)
{
curPlayer--;
}
if(direction == 1)
{
curPlayer++;
}
else
{
curPlayer--;
}
if(curPlayer > 10)
{
curPlayer = curPlayer - 10;
}
else if(curPlayer < 1)
{
curPlayer = curPlayer + 10;
}
}
return curPlayer;
在伪代码中:
set curPlayer to 1
set direction to 1
for(i is 1 to 100)
{
if i is divisible by 7 and direction is 1
{
set direction to 0
}
else if i is divisible by 7
{
set direction to 1
}
if i is divisible by 11 and direction is 1
{
increment curPlayer
}
else if i is divisible by 11
{
decrement curPlayer
}
if direction is 1
{
increment curPlayer
}
else
{
decrement curPlayer
}
if curPlayer is larger than 10 {
subtract 10 from curPlayer
}
if curPlayer is less than 1 {
add 10 to curPlayer
}
}
return curPlayer