2 条题解
-
0
简化一下题意: 给定一个长为 n 的字符串 s,表示 n 段时间,有三种情况,分别表示线上会议,线下会议和空闲时间; 线下会议只能在公司参加,线上会议在公司和家中均可参加,空闲时间可以做题 可以选择使用 t 段时间通勤去到公司,但只能去一次,且通勤时间能不能做题也不能参加会议 注意最后必须回到家中,所以必然会有两段通勤时间 总共可以翘掉 k 次会议,只有空闲时间或者被翘掉且不在通勤的时间可以做题
读完了题意后,这道题的大致轮廓就比较清晰了 我们可以发现由于只能去公司一次,所以只要确定了通勤时间后做题时间可以通过前缀和直接计算 计算过程就是把通勤时间内的会议数量 cnt 先和 k 作比较,然后大于就直接略过,小于就让 k 直接减去 cnt 然后对于通勤时间和在公司时间外的所有线下会议数量 cnt1 和 剩余的 k 作比较,小于也是直接略过不考虑,然后让剩余的 k 减一次 cnt1 接着就是把剩下空闲的时间和剩余可以被翘掉的会议加到答案中 可以发现此题数据不大,所以直接枚举通勤的时间然后比较计算最大即可 代码如下:
#include<bits/stdc++.h> #define ios ios::sync_with_stdio(0),cin.tie(0),cout.tie(0) using namespace std; const int N=8001; int n,k,t,pre1[N],pre2[N],pre3[N],mx=-1; string s; int gt_sm(int op,int l,int r){ if(op==1)return pre1[r]-pre1[l-1]; else if(op==2)return pre2[r]-pre2[l-1]; else return pre3[r]-pre3[l-1]; } int solve(int l,int r){ int res,tk=k,cnt; tk-=gt_sm(1,l-t,l-1)+gt_sm(2,l-t,l-1); tk-=gt_sm(1,r+1,r+t)+gt_sm(2,r+1,r+t); if(tk<0)return -1; l-=t+1,r=min(n+1,r+t+1); res=gt_sm(3,1,l)+gt_sm(3,r,n); cnt=gt_sm(1,1,l)+gt_sm(1,r,n); if(tk<cnt)return -1; cnt+=gt_sm(2,1,l)+gt_sm(2,r,n); return res+min(cnt,tk); } int main(){ ios; cin>>n>>k>>t>>s; for(int i=1;i<=n;++i){ pre1[i]=pre1[i-1],pre2[i]=pre2[i-1],pre3[i]=pre3[i-1]; if(s[i-1]=='1')pre1[i]++; else if(s[i-1]=='2')pre2[i]++; else pre3[i]++; } if(k>=pre1[n])cout<<min(n,k+pre3[n]),exit(0); for(int i=t+1;i<=n-t+1;++i) for(int j=i;j<=n-t;++j) mx=max(mx,solve(i,j)); cout<<mx; } -
0
简化一下题意: 给定一个长为 $n$ 的字符串 $s$,表示 $n$ 段时间,有三种情况,分别表示线上会议,线下会议和空闲时间; 线下会议只能在公司参加,线上会议在公司和家中均可参加,空闲时间可以做题 可以选择使用 $t$ 段时间通勤去到公司,但只能去一次,且通勤时间能不能做题也不能参加会议 **注意最后必须回到家中,所以必然会有两段通勤时间** 总共可以翘掉 $k$ 次会议,只有空闲时间或者被翘掉且不在通勤的时间可以做题 --- 读完了题意后,这道题的大致轮廓就比较清晰了 我们可以发现由于**只能去公司一次**,所以只要确定了通勤时间后做题时间可以通过前缀和直接计算 计算过程就是把通勤时间内的会议数量 $cnt$ 先和 $k$ 作比较,然后大于就直接略过,小于就让 $k$ 直接减去 $cnt$ 然后对于通勤时间和在公司时间外的所有线下会议数量 $cnt1$ 和 剩余的 $k$ 作比较,小于也是直接略过不考虑,然后让剩余的 $k$ 减一次 $cnt1$ 接着就是把剩下空闲的时间和剩余可以被翘掉的会议加到答案中 可以发现此题数据不大,所以直接枚举通勤的时间然后比较计算最大即可 代码如下:
#include<bits/stdc++.h> #define ios ios::sync_with_stdio(0),cin.tie(0),cout.tie(0) using namespace std; const int N=8001; int n,k,t,pre1[N],pre2[N],pre3[N],mx=-1; string s; int gt_sm(int op,int l,int r){ if(op==1)return pre1[r]-pre1[l-1]; else if(op==2)return pre2[r]-pre2[l-1]; else return pre3[r]-pre3[l-1]; } int solve(int l,int r){ int res,tk=k,cnt; tk-=gt_sm(1,l-t,l-1)+gt_sm(2,l-t,l-1); tk-=gt_sm(1,r+1,r+t)+gt_sm(2,r+1,r+t); if(tk<0)return -1; l-=t+1,r=min(n+1,r+t+1); res=gt_sm(3,1,l)+gt_sm(3,r,n); cnt=gt_sm(1,1,l)+gt_sm(1,r,n); if(tk<cnt)return -1; cnt+=gt_sm(2,1,l)+gt_sm(2,r,n); return res+min(cnt,tk); } int main(){ ios; cin>>n>>k>>t>>s; for(int i=1;i<=n;++i){ pre1[i]=pre1[i-1],pre2[i]=pre2[i-1],pre3[i]=pre3[i-1]; if(s[i-1]=='1')pre1[i]++; else if(s[i-1]=='2')pre2[i]++; else pre3[i]++; } if(k>=pre1[n])cout<<min(n,k+pre3[n]),exit(0); for(int i=t+1;i<=n-t+1;++i) for(int j=i;j<=n-t;++j) mx=max(mx,solve(i,j)); cout<<mx; }
- 1
信息
- ID
- 7668
- 时间
- 8000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 4
- 已通过
- 3
- 上传者