ACM第三周学习总结
一周所遇题型及解决办法
区间问题:
1.区间取两个数
题意:在若干区间内(>=2)取出两个数,求不重复数的最少个数。思路:用结构体表示区间始末位置,以末位置升序排列。将第一个数组的最大两个数存入数组a,再用下一个区间初位置与上一个末位置比较看是否有区间重叠。若区间重叠则再用循环比较数组中已存入的数与区间内数查重,若重复两个以上,则可跳过,若不满两个则从区间最大数开始补足两个数 。若区间不重叠则直接取最大两数。
代码实现:
cin>>n;
for(i=0; i<n; i++)
cin>>a[i].x>>a[i].y;
sort (a,a+n,cmp);
b[q]=a[0].y; q++; b[q]=a[0].y-1;
for(i=1; i<n; i++)
{ t=0; if(a[i].x-a[i-1].y<1)
{ for(j=0; j<=q; j++)
{ if(b[j]>=a[i].x&&b[j]<=a[i].y) t++; } if(t1)
{ q++; b[q]=a[i].y; }
if(t<1)
{ q++; b[q]=a[i].y; q++; b[q]=a[i].y-1; }} else
{ q++; b[q]=a[i].y; q++;b[q]=a[i].y; }
}
代码中多使用if语句和for语句,要注意顺序先后和因果关系。
总结:此题虽然只是取两个数,但方法用于取三(多)个数仍可使用。在解决问题时,排列结构体时容易以起始位置排列而使思路错误,所以要克服排列常排起始的套路。
2 .加工木棍问题
题意:加工的木棍有重量长度之分,加工时,只有后者都>前者才能继续使用加工机器,否则花时间调试,求调试最少次数。
思路:
结构体定义重量长度,两者都以升序排列,再比较重量(长度)即可。比较时还要定义每个木棍的状态来表示是否已经被加工。
代码:
bool cmp(S a,S b)
{ if(a.x!=b.x)
return a.x<b.x; return a.y<b.y;}
for(i=0; i<n; i++)
{ if(a[i].f0)
{ s++; t=i; }
for(j=t+1; j<n; j++)
{ if(a[j].f==0)
{ if(a[j].y>=a[t].y)
{ a[j].f=1; t=j; }
else continue; }
}}
cout<<s<<endl;q–;}
总结
根据vj所做题来说,区间问题
主要遇到覆盖问题,即后面的区间是否与前面相交,解决时大多需要先排序(排序要注意排序条件),根据要求(多是累计)得到答案。比较时看是否需要使用标记,或者记录,或者需要多次比较等等。
其他题目总结:
其他解决的问题还有骑车追赶问题,牛奶储存成本问题,方块移动问题,6*6装箱问题等这些问题基本需要寻找一定规律来解决问题。从多个方案中寻找最优。
如骑车问题(追赶前面的车),要求寻找骑车时间最短。此题原本以为需要求时间,速度和路程关系,但实际跳出题意则只是需要我们去求所有人(追赶的人)到达终点的时间,再选择最小值输出即可。所以问题的解决方案并不一定需要按照题意循规蹈矩,而要真正理解题意,用本质的方法解决更加省时省力。