2021-03-27

本文分享了ACM竞赛中遇到的区间问题解决方法,包括区间取数和加工木棍问题。强调了对区间进行以末位置排序的重要性,并提供了代码实现。此外,还提及了在处理这类问题时注意排序条件、使用标记和记录关键信息的技巧。总结中指出,理解题意并找到问题的本质是解决问题的关键,有时不必拘泥于题目的常规解法。
摘要由CSDN通过智能技术生成

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].f
0)
{ 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装箱问题等这些问题基本需要寻找一定规律来解决问题。从多个方案中寻找最优。
如骑车问题(追赶前面的车),要求寻找骑车时间最短。此题原本以为需要求时间,速度和路程关系,但实际跳出题意则只是需要我们去求所有人(追赶的人)到达终点的时间,再选择最小值输出即可。所以问题的解决方案并不一定需要按照题意循规蹈矩,而要真正理解题意,用本质的方法解决更加省时省力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值