[补题]C. Light Switches

C.Light Switches

[补题]C. Light Switches_第1张图片
思路:
注意到有周期为 2 ∗ k 2*k 2k 的周期性,所以需要做的就是先排序(也可以不排序,只需要找到最晚安装芯片的房间即可),最晚的芯片安装时间为 a n − 1 a_{n-1} an1,则答案区间为 [ a n − 1 , a n − 1 + k ) [a_{n-1},a_{n-1}+k) [an1,an1+k)
然后枚举前面的每个房间的芯片安装时间,根据周期性可以判断该房间的灯在答案区间内的状态,据此不断对 l 、 r l、r lr 进行修改。
最后进行判断,如果 l < r ll<r 则不存在,否则 l l l 即为答案。
代码:
(有两种思路可供参考,本质是一样的,只是在根据周期性缩减答案区间时采取的策略有所不同)

//1.0
#include 
#define endl '\n'
#define int long long
typedef long long ll;
using namespace std;

void solve();
signed main() {
	cin.tie(0)->ios::sync_with_stdio(0);
	int T = 1;
	cin >> T;
	while (T--) {
		solve();
	}
	return 0;
}

void solve() {
	int n,k;
	cin>>n>>k;
	int a[n];
	for(int i=0;i<n;i++){
		cin>>a[i];
	}
	sort(a,a+n);
	int l = a[n-1],r=a[n-1]+k-1; 
	for(int i=0;i<n-1;i++){
			a[i]=((l-a[i])/(2*k))*(2*k)+a[i];
			if(a[i]+k<l)a[i]+=2*k;  //使得与l,r有交集
			l=max(l,a[i]);
			r=min(r,a[i]+k-1);
	}
	
	if(l>r){cout<<"-1\n";return;}

	cout<<l<<endl;
}
//2.0
#include 
#define endl '\n'
#define int long long
typedef long long ll;
using namespace std;

void solve();
signed main() {
	cin.tie(0)->ios::sync_with_stdio(0);
	int T = 1;
	cin >> T;
	while (T--) {
		solve();
	}
	return 0;
}

void solve() {
	int n,k;
	cin>>n>>k;
	int a[n];
	int maxi=0,maxn=0;
	for(int i=0;i<n;i++){
		cin>>a[i];
		if(a[i]>maxn){   
			maxi=i;
			maxn=a[i];
		}
	}
	int base = maxn/(2*k)*(2*k);    
	int l = maxn%(2*k),r=l+k-1;    //这里将安装时间都mod周期
	for(int i=0;i<n;i++){
		if(i==maxi)continue;
		a[i]=a[i]%(2*k);
		if(a[i]+k<l){a[i]+=2*k;}   //使得与l,r有交集
		else if(a[i]>r){a[i]-=2*k;}
		l=max(l,a[i]);
		r=min(r,a[i]+k-1);
	}
	
	if(l>r){cout<<"-1\n";return;}
	
	cout<<l+base<<endl;
}

你可能感兴趣的:(题解/补题,c语言,c++,算法)