1. 程式人生 > 實用技巧 >摺紙 (模擬)

摺紙 (模擬)

暑假大集訓模擬賽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;
}