[补题]C. Light Switches

C.Light Switches

在这里插入图片描述
思路:
注意到有周期为 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 l<r l<r 则不存在,否则 l l l 即为答案。
代码:
(有两种思路可供参考,本质是一样的,只是在根据周期性缩减答案区间时采取的策略有所不同)

//1.0
#include <bits/stdc++.h>
#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 <bits/stdc++.h>
#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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值