C.Light Switches
思路:
注意到有周期为
2
∗
k
2*k
2∗k 的周期性,所以需要做的就是先排序(也可以不排序,只需要找到最晚安装芯片的房间即可),最晚的芯片安装时间为
a
n
−
1
a_{n-1}
an−1,则答案区间为
[
a
n
−
1
,
a
n
−
1
+
k
)
[a_{n-1},a_{n-1}+k)
[an−1,an−1+k)
然后枚举前面的每个房间的芯片安装时间,根据周期性可以判断该房间的灯在答案区间内的状态,据此不断对
l
、
r
l、r
l、r 进行修改。
最后进行判断,如果
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;
}