HRBUST OJ 2063:
http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=2063
分析:
A.萌萌哒十五酱的情书~ | |||||
| |||||
Description | |||||
因为十五酱实在是太萌了所以她经常会收到爱慕者的情书!!!!!!!!!!~ 当然因为情书太多了所以她没有时间都读完 于是她把给她的情书从左到右划分成n个区域,在每个区域的边界依次表上0~n,然后她将经行m次操作,每次她都会选择一个数字ai,把纸带沿这个数字当前所在的位置翻折(假如已经在边界上了那就相当于什么都不做啦~)。 十五想知道经过m次对折之后她还需要读多长的情书。 | |||||
Input | |||||
多组数据 第一行为两个正整数n(1<=n<=10^18),m(m<=3000),表示纸带的长度和操作的次数。 接下来的一行为m个整数ai(1<=ai<=n),其中ai表示第i次选择的数字。 | |||||
Output | |||||
多组数据输出 输出文件中每组数据输出一行为一个整数,即纸带最后的长度。 | |||||
Sample Input | |||||
5 2 3 5 | |||||
Sample Output | |||||
2 | |||||
Hint | |||||
十五酱最萌了昂~ |
分析:
题目是定义一个长度为n的纸条,然后进行m次翻折,最后求出长度是多少。例题中长度为5,2次操作如下图。
定义一个结构体存储区间端点例如题目中存储(0,5)。然后将每次操作存在数组里面。
(0,5) ->(0,3) ->(1,3);
3 5
;
当是3的时候在(0,5)之间,翻折后区间(0,3)比(3,5)长,所以取(0,3);
当是5的时候在不在(0,3)之间 但是第一步 3 的操作使 5 与 1 重合 所以 5 相当于 1 。
1 在 (0,3)之间,取区间长度大的(1,3);
最后答案也就是 3-1 = 2;
PS:最初看到题目和数据后一点思路没有,150MS,10^18,看着就吓人。想了一会感觉定义一个结构体里面存着最长的区间端点然后对着区间端点进行操作。前一个小时,根本没进入情绪,看了一眼,没一道会做的。然后最开始琢磨A题,最后2,3分钟ac了。
#include <iostream>
using namespace std;
struct mp
{
long long a,b;
};
int main()
{
long long m,n,x,i,j,w[3003];
while(cin>>n>>m)
{
mp x,t[m];
x.a=0,x.b=n;
for(i=0; i<m; i++)cin>>w[i];
for(i=0; i<m; i++)
{
if(w[i]>x.a&&w[i]<x.b)
{
if(w[i]>(x.a+x.b)/2.0) x.b=w[i];
else x.a=w[i];
}
else
{
long long k = w[i];
for(j=0; j<i; j++)
if(k<t[j].a) k = 2*t[j].a - k;
else if(k>t[j].b) k = 2*t[j].b - k;
if(k>x.a&&k<x.b)
{
if(k>(x.a+x.b)/2.0) x.b=k;
else x.a=k;
}
}
t[i].a = x.a ,t[i].b = x.b;
}
cout<<x.b - x.a<<endl;
}
return 0;
}
结果:
RunID | ID | JudgeStatus | Language | Time | Memory | Length | SubmitTime |
79762 | A | Accepted | G++ | 138ms | 1196k | 1364B | 2014-03-23 16:56:02 |