首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

一路逻辑编程题目。小菜求大神出马

2012-12-26 
一道逻辑编程题目。小菜求大神出马大厅里有100盏灯,每盏灯都编了号码,分别为1-100。每盏灯由一个开关来控制。

一道逻辑编程题目。小菜求大神出马
大厅里有100盏灯,每盏灯都编了号码,分别为1-100。每盏灯由一个开关来控制。(开关按一下,灯亮,再按一下灯灭。开关的编号与被控制的灯相同。)开始时,灯是全灭的。现在按照以下规则按动开关。
第一次,将所有的灯点亮。
第二次,将所有2的倍数的开关按一下。
第三次,将所有3的倍数的开关按一下。
以此类推。第N次,将所有N的倍数的开关按一下。
问第N次(N大于等于2,且小于等于100)按完以后,大厅里还有几盏灯是亮的。


求思路加代码  谢谢
[最优解释]


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace _01
{
    class Program
    {
        static int divisor = 2;     //除数因子,因为从第二次开始算,所以取2
        static int[] lights = new int[100];    //100个灯的数组
            
        static void Main(string[] args)
        {
            for (int i = 0; i < lights.Length; i++)
            {
                lights[i] = 1;               //初始化所有灯的值为1(任何整数均可,打开就是正的,关了就乘-1
            }
            int n =100;
            int result = count(n);         //第100次的结果
            Console.WriteLine("第{0}次,大厅里还有{1}盏灯是亮的",n,result);
            Console.ReadKey();
        }
        static int count(int n)
        {
            if (n >= 2)    //从2次起算,1次直接返回100
            {
                loop(n);   //暴力循环,模拟开关n次
                int sum = 0;
                for (int i = 0; i < lights.Length; i++)
                {
                    if (lights[i]> 0)
                    {
                        sum += 1;     //把最后循环的结果,遍历一次,大于0的表示灯的状态是开,用sum记录
                    }
                }
                return sum;


            }
            else
            {
                return 100;
            }
        }
        static void loop(int n)
        {
            if (n < 2)        
            {
                return;
            }
            for (int i = 2; i <= 100; i++)          //用循环模拟按灯的结果,因为用到灯的序号,所以i从2开始,100结束
            {
                if (i % divisor == 0)      //当i为因素的倍数
                {
                    lights[i-1] = lights[i-1] * -1;    //使该灯的值改变一次
                }
            }
            divisor++;     //因素加1
            loop(n - 1);   //继续下一次循环,直到n=2结束
        }

    }
}



完全的暴力算法,除了递归想不到别的方法了
[其他解释]

        private void button1_Click(object sender, EventArgs e)
        {
            for (int i = 1; i <= 100; i++)
            {
                entity en = new entity();
                en.index = i;
                en.flag = true;
                allLight.Add(en);
            }
            cal(4);
        }

        List<entity> allLight = new List<entity>();
        private void cal(int times)
        {


            for (int i = 2; i <= times; i++)
            {
                List<entity> allPxNum = allLight.FindAll(x => (x.index % times == 0));
                foreach (entity en in allPxNum)
                {
                    en.flag = !en.flag;
                    allLight[en.index - 1] = en;
                }
            }
            List<entity> allLigthTrue = allLight.Where(x => (x.flag == true)).ToList();
            int lightNum = allLight.Where(x => (x.flag == true)).Count();
            System.Diagnostics.Debug.WriteLine("还有" + lightNum + "灯亮");

            foreach (entity en in allLigthTrue)
            {
                System.Diagnostics.Debug.WriteLine(en.index + "灯亮");
            }
        }

        public class entity
        {
            public int index { get; set; }
            public bool flag { get; set; }
        }



试试
[其他解释]
http://hi.baidu.com/zhiliangshouhe/item/d60660874a4dc7dbd0f8cd54
[其他解释]
那个帖子对吗?如果只有平方的都亮着,那么100以内的质素怎么说?所有的质素只按一次不是吗?
[其他解释]
我看错了,刚开始灯全亮啊,汗
[其他解释]

  int[100] light ;
  int rst=0;//结果
  
  for(int i=1;i<=100;i++){
    light[i-1]=1;//亮
}  int N;//N为次数
  if(N=1){
     rst=100;

   for(int j=2;j<=N){
     for(int i=1;i<=100;i++){
        if(i%j==0){
            if(light[i-1]==1)
                 {light[i-1]=0}
             else


                 {light[i-1]=1}   
  }
 }
}
 for(int i=1;i<=100;i++){
   if(light[i-1]=1){
     rst+=1;
  }
}


 只提供个思路,怎么写还得看楼主的。。
[其他解释]
数学学的不好,最简单的办法就是双重循环,定义一个长度为100的bool数组,
外层是i=1;i<=n;i++,
里层是j=0;j<100;j=j+n
然后循环里对数组的值反转
arr[j]=!arr[j]
[其他解释]
引用:
http://hi.baidu.com/zhiliangshouhe/item/d60660874a4dc7dbd0f8cd54


+1

代码

        static void GetLightNums(int n)
        {
            for (int i = 1; i * i <= n; ++i) Console.Write(i * i + " ");
        }

[其他解释]
我也来贴一下我的代码:

public static bool IsPrime(int n)
{
    if (n == 2) return true;
    if (n < 2 
[其他解释]
 n % 2 == 0) return false;

    for (int i = 3; i < Math.Sqrt(n); i++)
    {
        if (n % i == 0) return false;
    }

    return true;
}
public static int GetLightRemainingCount(int lightCount, int filterCount)
{
    if (filterCount < 1) throw new ArgumentException();
    if (filterCount == 1) return lightCount;

    var lights = new bool[lightCount + 1];
    Parallel.For(0, lightCount + 1, i => lights[i] = true);

    for (int filter = 2; filter <= filterCount; filter++)
    {
        if (!IsPrime(filter)) continue;

        for (int i = 1; i <= lightCount; i += filter)
        {
            lights[i] = false;
        }
    }

    return lights.Where(light => light == true).Count() - 1;
}


说明:

第一个 IsPrime 是判断是不是素数。为什么要判断?一个个循环去除 1 ~ N 个倍数因子,显然是不合适的,然后发现,如果要过滤的话,第一次就把偶数给全部排除了。从第二次开始,其实如果不是素数的因子可以全部忽略!无需去用剩下的每一个Index 去除因子。然后每次遇到一个倍数因子,就从该因子开始向后以其倍数增长。

举个例子,如果当前因子是 15,因为 15 不是素数,所以直接忽略,为什么?因为 15 = 3 * 5,3 和 5 的倍数都已经排除了,更何况 15,所以直接忽略。
如果当前因子是 7,那就以 7 的倍数为 for 循环的步长来增长,将该素数的倍数对应的 light 全部 turn  off 掉。



这是我的一些想法。
[其他解释]


readonly bool[] lights = new bool[100];
        private void pressOnce(int press)
        {
            for (int currentCount = press; currentCount < 100; currentCount = currentCount + press) 
            {
                lights[currentCount - 1] = !lights[currentCount - 1];
            }
            
        }

//按第一次时也可调用该函数,press为第几次调用(第几次按)
[其他解释]


    Dim i As Integer = 0
    Dim a(99) As Object
    Dim f As Boolean
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        If i = 0 Then '第一次的时候开灯
            For j As Integer = 0 To a.Length - 1
                a(j) = True
            Next
        ElseIf i > 0 Then
            For j As Integer = 0 To a.Length - 1
                If (j + 1) Mod (i + 1) = 0 Then
                    If a(j) = True Then
                        a(j) = False
                    Else
                        a(j) = True
                    End If
                End If
            Next
        End If

        Dim strMsg As String = String.Empty
        Me.ListBox1.Items.Clear()
        For j As Integer = 0 To a.Length - 1
            If a(j) = True Then


                strMsg = "第" & j + 1 & "盏灯是亮的"
            Else
                strMsg = "第" & j + 1 & "盏灯是灭的"
            End If
            Me.ListBox1.Items.Add(strMsg)
        Next

        i = i + 1
    End Sub


[其他解释]
我贴下我的代码,忘大家轻拍,变量命名的不是很好

 static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Console.WriteLine("输入x退出,");

            while (true)
            {
                Console.WriteLine("请输入经过N次,N为1-100之间的数:");
                string wReadLine = Console.ReadLine();

                if (wReadLine == "X" 
[其他解释]
 wReadLine == "x")
                    break;

                int N;
                if (int.TryParse(wReadLine, out N))
                {
                    Bulb wBult = new Bulb();
                    for (int i = 1; i <= N; i++)
                        wBult.TurnLightOn(i);
                    wBult.CountBult();
                }
                else 
                {
                    Console.WriteLine("输入N的数据格式不正确");
                }


                Console.WriteLine("\t\n");
            }
        }
    }

    class Bulb
    {
        bool[] mBulb = new bool[100];

        public void TurnLightOn(int label)
        {
            if (!(label >= 1 && label <= 100))
                Console.WriteLine("输入的N不在1-100内");

            List<int> wLabelList = new List<int>();

            for (int i = 1; ; i++)
            {
                if (i * label > 100)
                    break;

                wLabelList.Add(i * label);
            }

            for (int i = 0; i < wLabelList.Count; i++)
            {
                mBulb[wLabelList[i] - 1] = !mBulb[wLabelList[i] - 1];
            }
        }

        public void CountBult()
        {
            int wNum = 0;
            for (int i = 0; i < 100; i++)
            {
                if (mBulb[i])
                    wNum++;
            }
            Console.WriteLine("还有{0}盏灯亮着", wNum);
        }
    }


TurnLightOn方法是输入执行某一次 灯的状态改变,CountBult是数出还有几盏灯亮着

热点排行