zoukankan      html  css  js  c++  java
  • 校门外的树和memset

    题目描述 (NOIP2005普及组第二题)

    某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是11米。我们可以把马路看成一个数轴,马路的一端在数轴00的位置,另一端在LL的位置;数轴上的每个整数点,即0,1,2,…,L0,1,2,,L,都种有一棵树。

    由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。

    输入输出格式

    输入格式:

    第一行有22个整数L(1L10000)和M(1M100),LL代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。
    接下来的M行每行包含22个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。

    输出格式:

    11个整数,表示马路上剩余的树的数目。

    输入输出样例

    输入样例#1:                                         输出样例#1: 

    500 3                             298
    150 300
    100 200
    470 471

    说明

    对于20%的数据,区域之间没有重合的部分;

    对于其它的数据,区域之间有重合的情况。

    解题策略

    1.直接模拟,马路上修建地铁占用的点标记为1,未被占用的点标记为0。

    代码如下:

     1 #include <bits/stdc++.h>
     2 #include <stdlib.h>
     3 
     4 using namespace std;
     5 typedef struct {
     6     int start, end;
     7 } node;
     8 
     9 int main(int argc, const char *argv[])
    10 {
    11     int L, M, ans = 0;
    12     scanf ("%d%d", &L, &M);
    13     int a[L+1];
    14     node aa[M];
    15     memset(a, 0, sizeof(a));
    16     for (int i = 0; i < M; i++)
    17         scanf ("%d%d", &aa[i].start, &aa[i].end);
    18     for (int i = 0; i < M; i++) {
    19         int ss = aa[i].start;
    20         int ee = aa[i].end;
    21         for (int j = ss; j <= ee; j++) a[j] = 1;
    22     }
    23     for (int i = 0; i <= L; i++) 
    24         if (a[i] == 0) ans++;
    25     printf ("%d
    ", ans);
    26     return 0;
    27 }

    但是测试的时候出现了一个问题,关于memset函数。在第15行,将数组a全部赋值为1时

    memset(a, 1, sizeof(a));

    通过中间结果测试出了问题,发现并没有赋值成功。

    如下demo是可以的,能把数组中的元素值都设置成字符1.

     1 #include <iostream>
     2 #include <cstring>
     3 using namespace std;
     4 int main()
     5 {
     6     char a[5];
     7     memset(a,'1',5);
     8     for(int i=0;i<5;i++)
     9         cout<<a[i]<<"";
    10     system("pause");
    11     return 0;
    12 }

    如下程序想把数组中的元素值设置成1,却是不可行的!

    #include <iostream>
    #include <cstring>
    #include <windows.h>
    using namespace std;
    int main()
    {
        int a[5];
        memset(a,1,20);       //也等价于memset(a,1,sizeof(a));
        for(int i=0;i<5;i++)
            cout<<a[i]<<"";
        system("pause");
        return 0;
    }
    因为第一个程序的数组a是char型的,字符型占据内存大小是1Byte,而memset函数也是以Byte为单位进行赋值的,所以你输出没有问题。而第二个程序a是整型(int)的,使用 memset还是按字节赋值,这样赋值完以后,每个数组元素的值实际上是0x01010101即十进制的16843009。如果用memset(a,1,20),就是对a指向的内存的20个字节进行赋值,每个都用数1去填充,转为二进制后,1就是00000001,占一个字节。一个int元素是4字节,合一起是0000 0001,0000 0001,0000 0001,0000 0001,转化成十六进制就是0x01010101,就等于16843009,就完成了对一个int元素的赋值了。
    Work hard in silence,let success make the noise.
  • 相关阅读:
    如何在perl中一次执行多条shell命令
    Spring.netAOP 搭建网站通知服务(1)
    使用Spring.net AOP 实现积分服务
    我得第一帖@2011
    ADO.NET+存储过程+事务的一个奇怪问题,求探讨
    (一)项目说明及程序框架说明——.NET开发完整案例(企业邮箱系统)
    2.系统设置网站配置网站信息配置
    .NET企业邮箱系统项目说明及文章索引——20118.13更新
    .Net内容管理系统开发实例项目说明及文章索引——2011825更新
    后端小记录
  • 原文地址:https://www.cnblogs.com/nixrpm/p/11232313.html
Copyright © 2011-2022 走看看