折纸 (模拟)
暑假大集训模拟赛12 T1
折纸
算法分析:
- 对于每一次翻折给出一个点 但是我们并不知道这个点的具体位置是多少 如果我们开一个数组维护这个点的位置 那肯定会炸掉 (1e18跟你闹呢?)
- 但是我们的操作次数却很少 最多只有3000次 而且我们只需要操作点的位置 所以我们可以在把当前次的操作点确定下来 然后通过当前次的操作处理出来对后面操作的影响 然后以此类推
- 这里要注意的是我们要将这个纸条不断向里折 如果只向同一个方向折会炸long long
Code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 3e3+10;
ll a[maxn];
int main(){
int T;scanf("%d",&T);
while(T--){
ll n,m;scanf("%lld%lld",&n,&m);
ll l = 0;//左右边界
ll r = n;
for(int i = 1;i <= m;++i)scanf("%lld",&a[i]);//输入操作点
for(int i = 1;i <= m;++i){
ll now = a[i];//以当前操作点为基准 处理后面的操作点
if(l + r > now * 2){//如果当前操作点在区间的中点左边 向右折
for(int j = i + 1;j <= m;++j)
if(a[j] >= l && a[j] < now)a[j] = now * 2 - a[j];//将后面的操作点处理 把左边的点都折过去
l = now;//修改左边界
}
//向左折的情况
else {
for(int j = i + 1;j <= m;++j)
if(a[j] > now && a[j] <= r)a[j] = now * 2 - a[j];
r = now;
}
}
printf("%lld\n",r - l);
}
return 0;
}
如初见 与初见