通宵教室

版权声明:沉迷代码,难以自拔 https://blog.csdn.net/qq_33846054/article/details/50581596

突然觉得刷Acm的水题并不能让自己学到什么新知识,于是想尝试一种新的方式,和代码谈一场有情调的恋爱。
提醒自己注意几个问题:(摘自“如何成为一名卓越的前端工程师”)
1.别光解决问题,想想究竟发生了什么
我发现很多情况下,当你遇到问题的时候,你只是解决当下的问题罢了。但是如果你永远不花时间理解问题的本源,你将一次又一次的面对相同的问题。花一些时间找出为什么,这看上去费时费力,但是我保证它会节省你未来的时间。在完全理解整个系统之后,你就不需要总去猜测和论证了。
2. 阅读别人的代码
出于乐趣阅读别人的代码可能并不是你每周六晚上会想到的娱乐项目,但是这毫无疑问是你成为优秀工程师的最佳途径。
3.把你学到的东西都记录下来
写作、演讲、做 demo 是强迫自己完全深入理解一件事的最佳方式。就算你写的东西没有人看,整个过程也会让你受益匪浅。

寒假亦为一年的新开始,不能不把专业课程放于较低的位置,而是应该着重突破,才能让自己清楚地知道在大学里究竟有应该学到什么。所以我下定决心,把记录博客这件事情坚持下去,当作学习专业文化知识和帮助自己突破瓶颈的一种方式,倘若年年如此,这个记录我从计算机科学技术课程的小白到有了一定历练的程序猿的Home,也便有了它存在的意义。

二 通宵教室 nefu 6

1 description

高校扩招,教室一度变得很紧张。学生白天上自习的地方较少,晚上教室又闲置着,怎样才能充分利用教学资源,扩大学生自习时空呢?通宵教室解决学生自习空间有限和教学资源不充分利用的问题。开放通宵教室促进了学生学习观念的转变,以前课堂内外基本上是听老师安排,现在是学生自觉在学习。晚上学习效率高、生理调节能力强的学生已经尝到了甜头。好学、考研、辅修、创作的学生又有了一片新的学习时空。
但是通宵教室对传统的学生管理工作带来了一系列的问题。如果通宵教室的利用率不高的话,将教室的所有灯都打开,还会极大地浪费能源。
现在学校对通宵教室灯光使用做一个新的尝试。假设有N个人使用通宵教室,教室里有N盏灯,每个人和每盏灯都有一个编号。开始所有的灯都没打开,第一个人进教室将所有的灯都打开,第二个人将所有的偶数号的灯都关掉,第三个人对所有3的倍数的灯进行如下操作:如果灯开着,就将它关掉,如果灯关着,就将它打开,……,第i个人对所有i的倍数的灯进行如下操作:如果灯开着,就将它关掉,如果灯关着,就将它打开,重复这样的过程,一直到第N个人完成这样的操作。
现在,教室管理员向你求助,他希望知道,完成这样的过程后,教室里开着的灯还有多少盏?

input
有多组测试数据。第一行是一个正整数T(1<=T<=10000),表示有多少组测试数据。
以下有T行,每行一个测试数据,包含唯一的一个正整数N(1 <= n < 2^32,)。

output
对于每个测试数据,输出一行包含唯一的一个整数:表示完成这样的过程后,教室里开着的灯的盏数。

sample_input
2
1
2

sample_output
1
1

2 正常的思路:

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#define max 100000000  
using namespace std;

int main()
{
    int n,i,j,a[max],count,t;
    cin>>t;
    while (t--)
    {count=0;
        cin>>n;
        memset(a,0,sizeof(a));
        for (i=1;i<=n;i++)                         
            for (j=1;j<=n;j++)
        {
            if (j%i==0)
            {
                a[j]=!a[j];
            }
        }
        for (i=1;i<=n;i++)
            if (a[i]==1)
            count++;
        cout << count << endl;
    }

    return 0;
}

注意:
一。define 函数的用法

  1.   简单的define定义
    

define MAXTIME 1000
一个简单的MAXTIME就定义好了,它代表1000,如果在程序里面写
if(i<MAXTIME){…}
编译器在处理这个代码之前会对MAXTIME进行处理替换为1000。
这样的定义看起来类似于普通的常量定义CONST,但也有着不同,因为define的定义更像是简单的文本替换,而不是作为一个量来使用,这个问题在下面反映的尤为突出。
2.define的“函数定义”
define可以像函数那样接受一些参数,如下
define max(x,y) (x)>(y)?(x):(y);
这个定义就将返回两个数中较大的那个,看到了吗?因为这个“函数”没有类型检查,就好像一个函数模板似的,当然,它绝对没有模板那么安全就是了。可以作为一个简单的模板来使用而已。
但是这样做的话存在隐患,例子如下:
define Add(a,b) a+b;
在一般使用的时候是没有问题的,但是如果遇到如:c * Add(a,b) * d的时候就会出现问题,代数式的本意是a+b然后去和c,d相乘,但是因为使用了define(它只是一个简单的替换),所以式子实际上变成了
ca + bd
另外举一个例子:
define pin (int*);
pin a,b;
本意是a和b都是int型指针,但是实际上变成int* a,b;
a是int型指针,而b是int型变量。
这是应该使用typedef来代替define,这样a和b就都是int型指针了。
所以我们在定义的时候,养成一个良好的习惯,建议所有的层次都要加括号。

二。memset函数的用法(头文件 string.h)
int data[100];
memset (data,x,sizeof(data)) 为给data数组赋予初值为X

三。输入T组数据的方法

四。设置内外两组循环,外循环表示第i个同学,内循环表示对于每个同学的n盏灯;1表示灯亮,0表示灯灭;对i的倍数的灯,即能够整除i;最最重要,若开即关,若关即开,用a[j]=!a[j]表示。

3 但是容易超时,所以,转换思路

一开始灯为灭,若有偶数个因子则仍为灭的,所以要想灯亮,灯的序号必须有奇数个因子。

#include <iostream>

using namespace std;

int main()
{
    int i,j,t,a,n;
    long long count;
    cin>>t;
    while (t--)
    {a=0;count=0;
        cin>>n;
        for (i=1;i<=n;i++)
    for (j=1;j<=i;j++)
    if (i%j==0)
        a++;
        if (a%2!=0)
        count++;
    cout << count<< endl;
    }

    return 0;
}
这样仍然超时。

如果一个数是完全平方数,那么它的因子的个数一定是奇数?
答:X2的因子至少有(1,x,x2)若X2还有因子的话一定是两个不同的数相乘设还有2n个因子3+2n (n>=0)所以为奇数
假设有25盏灯,灯的序号从1到25,25开根号为5,也就是1-5的平方,所以25以内共有5个完全平方数。

#include <iostream>
#include <math.h>
using namespace std;

int main()
{
    long long t,n;

    cin>>t;
    while (t--)
    {
        cin>>n;

    cout << (long long)sqrt(n)<< endl;
    }

    return 0;
}

全部定义longlong,开sqrt后仍旧为整型数据,所以强制转换

猜你喜欢

转载自blog.csdn.net/qq_33846054/article/details/50581596