折纸 (模拟)

暑假大集训模拟赛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;
}

posted @ 2020-08-02 10:37  HISKrrr  阅读(224)  评论(0编辑  收藏  举报