C/C++ 中的模拟算法实现
simulation algorithm implementation in C/C++
让一排8000lamp秒。最初,只有位于左侧的那个被点亮。
然后,每秒执行以下操作:每个 lamp 改变状态(打开或关闭),如果它左边的那个在一秒钟前被点亮。最左边的 lamp 一直亮着。此操作是瞬时的。
当右端的 lamp 第一次亮起时,该过程停止。
有多少盏灯亮着?
我下面的问题实现是假的,你能帮帮我吗?
#include <cstdio>
int t[8001][2];
int main()
{
t[1][0] = 1;
t[1][1] = 1;
int cpt1 = 0, ip = 0;
while (t[8000][0] != 1 && t[8000][1] != 1)
{
ip++;
for (int j=2;j<8001;j++)
{
if(t[j-1][!(ip&1)])
t[j][(ip & 1)] = !t[j][!(ip & 1)];
}
}
for(int j = 1;j < 8001; j++)
cpt1 += t[j][1];
printf("cpt=%d\n", cpt1);
}
当左边没有变化时,代码缺少更新。
代码简化(基于零的偏移量,bool
的使用)并在下面更正
#include<stdbool.h>
#include<stdio.h>
#define N 8000
bool t[N][2];
int main(void) {
t[0][0] = true;
t[0][1] = true;
int ip = 0;
while (t[N - 1][0] == 0 && t[N - 1][1] == 0) {
ip = !ip;
for (int j = 1; j < N; j++) {
if (t[j - 1][!ip]) {
t[j][ip] = !t[j][!ip];
} else {
t[j][ip] = t[j][!ip]; // add
}
}
}
int cpt1 = 0;
for (int j = 0; j < N; j++) {
cpt1 += t[j][1];
}
printf("N=%d cpt=%d\n", N, cpt1);
return 0;
}
输出
N=8000 cpt=2048
以下建议代码:
- 干净地编译
- 使用 C 头文件而不是 C++ 头文件
- 执行所需的操作,但不是最快的算法
- 被大量评论
现在建议的代码:
#include <stdio.h>
int t1[8000]; // initially all zeros
int t2[8000];
int main( void )
{
// setup initial conditions
int numLitLights = 0;
t1[0] = 1;
// while stop condition not true
while ( t1[7999] != 1 )
{
// make one pass through lamps
// update values
for (int j=0; j<7999; j++)
{
if( t1[j] )
{
t2[j+1] = ( t1[j+1] )? 0 : 1;
}
}
// update original
for( int j=0; j< 8000; j++ )
{
t1[j] = t2[j];
}
}
// count lit lamps
for(int j = 0; j < 8000; j++)
{
if( t1[j] )
{
numLitLights++;
}
}
// output number of lit lamps
printf( "number of lit lamps: %d\n", numLitLights );
} // end function: main
结果(点亮的灯数)为
1024
让一排8000lamp秒。最初,只有位于左侧的那个被点亮。 然后,每秒执行以下操作:每个 lamp 改变状态(打开或关闭),如果它左边的那个在一秒钟前被点亮。最左边的 lamp 一直亮着。此操作是瞬时的。 当右端的 lamp 第一次亮起时,该过程停止。 有多少盏灯亮着?
我下面的问题实现是假的,你能帮帮我吗?
#include <cstdio>
int t[8001][2];
int main()
{
t[1][0] = 1;
t[1][1] = 1;
int cpt1 = 0, ip = 0;
while (t[8000][0] != 1 && t[8000][1] != 1)
{
ip++;
for (int j=2;j<8001;j++)
{
if(t[j-1][!(ip&1)])
t[j][(ip & 1)] = !t[j][!(ip & 1)];
}
}
for(int j = 1;j < 8001; j++)
cpt1 += t[j][1];
printf("cpt=%d\n", cpt1);
}
当左边没有变化时,代码缺少更新。
代码简化(基于零的偏移量,bool
的使用)并在下面更正
#include<stdbool.h>
#include<stdio.h>
#define N 8000
bool t[N][2];
int main(void) {
t[0][0] = true;
t[0][1] = true;
int ip = 0;
while (t[N - 1][0] == 0 && t[N - 1][1] == 0) {
ip = !ip;
for (int j = 1; j < N; j++) {
if (t[j - 1][!ip]) {
t[j][ip] = !t[j][!ip];
} else {
t[j][ip] = t[j][!ip]; // add
}
}
}
int cpt1 = 0;
for (int j = 0; j < N; j++) {
cpt1 += t[j][1];
}
printf("N=%d cpt=%d\n", N, cpt1);
return 0;
}
输出
N=8000 cpt=2048
以下建议代码:
- 干净地编译
- 使用 C 头文件而不是 C++ 头文件
- 执行所需的操作,但不是最快的算法
- 被大量评论
现在建议的代码:
#include <stdio.h>
int t1[8000]; // initially all zeros
int t2[8000];
int main( void )
{
// setup initial conditions
int numLitLights = 0;
t1[0] = 1;
// while stop condition not true
while ( t1[7999] != 1 )
{
// make one pass through lamps
// update values
for (int j=0; j<7999; j++)
{
if( t1[j] )
{
t2[j+1] = ( t1[j+1] )? 0 : 1;
}
}
// update original
for( int j=0; j< 8000; j++ )
{
t1[j] = t2[j];
}
}
// count lit lamps
for(int j = 0; j < 8000; j++)
{
if( t1[j] )
{
numLitLights++;
}
}
// output number of lit lamps
printf( "number of lit lamps: %d\n", numLitLights );
} // end function: main
结果(点亮的灯数)为
1024