题意:在初始状态下每隔a秒就转换开关一次,问最多有多少个开关能在同一时刻亮起;
很明显就是筛相同时间段;我自己手动模拟了一遍可以这样写:
比如第一个案例:
然后用map边标记边统计最大值;
其实我写完后看了大佬们的代码,我的效率太低了;他们直接用下标去看是不是被a的倍数去记录的区间,还用到了异或操作,那个代码确实很简单:(值得学习)
大佬代码:
int main() {
ios_base::sync_with_stdio(false);
cin >> n;
cin >> s;
for(int i = 0; i < n; i++) {
cin >> a >> b;
int sw = s[i] - '0';
for(int j = 0; j <= 10000; j++) {
if(j >= b && (j - b) % a == 0)//这里直接判断倍数就OK了
sw ^= 1;//异或 为0或者1
v[j] += sw;//记录区间
}
}
for(int i = 0; i < N; i++)
ans = max(ans, v[i]);//取最大值
cout << ans << '\n';
}
AC代码:
#include<bits/stdc++.h>
using namespace std;
map<int,int> mm;
int main(){
int n,a,b,Max=0;
scanf("%d",&n);
string s;
cin>>s;
for(int i=0;i<n;i++){
scanf("%d %d",&a,&b);
if(s[i]=='1'){
for(int j=0;j<b;j++){
mm[j]++;
Max=max(Max,mm[j]);
}
for(int j=2;j<=1000;j+=2){
for(int k=b+(j-1)*a;k<=b+j*a-1;k++){
mm[k]++;
Max=max(Max,mm[k]);
}
}
}else{
for(int j=1;j<=1000;j+=2){
for(int k=b+(j-1)*a;k<=b+j*a-1;k++){
mm[k]++;
Max=max(Max,mm[k]);
}
}
}
}
printf("%d\n",Max);
return 0;
}