for (int i = 1;i <= n;++i) { cin>>str; if (str == ";")//该行为空行 { Do something! } for (int j = 0;j < str.size ();++j) { if ('0' <= str[j] && str[j] <= '9')//具体信息 { Do something! } if (str[j] == '-')//分隔符 { Do something! } if (str[j] == ',' || str[j] == ';')//一个信息的结束标志 { Do something! } } }
根据以上程序,我们可以将处理输入分成四个部分(四个 if 语句)。
如果该行只有一个 ;,那么没有需要处理的船,直接跳过即可。
如果遇到数字,那么转化成 int 类型进行存储。
如果遇到分隔符 -,说明有连续一段,标记并记录 -左边的数 a = num。
如果遇到结束的标志 , 或 ;,根据之前的标记进行判断是一个数还是一段区间,然后记录下来 a = b = num 或是 b = num(此处 $a$ 在分隔符的位置已经记录下来)
$\textbf{判断相交}$
不难发现应该在第四个 if 语句中操作。开两个数组分别记录最新连通块的结点与大小,并开一个记录每个起始位置与终止位置的结构体。
1 2
fa[++cnt] = cnt,sz[cnt] = b - a + 1;//结点与大小 _now[++k] = {a,b,cnt};//结点为 cnt 的连通块的信息
然后就是判断与上一行有无相交,有相交就直接合并,用 while 循环就能解决。
1 2 3 4 5
//kk 上一行的结点个数 //be[i] 上一行的信息 b[i].f,b[i].s,b[i].tmp 分别表示终止,起始与结点 //w 从 1 开始循环 while (w <= kk && be[w].f < a) ++w;//与上一行没有相交 while (w <= kk && be[w].s <= b) _union (_now[k].tmp,be[w].tmp),++w;//有相交就合并