校门外的树和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.
原文地址:https://www.cnblogs.com/nixrpm/p/11232313.html