洛谷P14118 题解
思维路径
首先我们显然可以暴力模拟m次用餐情况,得到答案,但是这显然会超时。
进而模拟整个过程,可以发现每种食材会在会提升第偶数个人的幸福值。
由此我们可以推出在经过偶数圈用餐后,火锅内的食材会恢复到全 \(0\) 的状态,即产生了循环。
因此我们不需要循环 \(m\) 次来计算,而是只需要循环 \(2n\) 次,找出一次循环后的情形,就可以轻松求解。
实现细节
由于 \(m\) 不一定是 \(2n\) 的整数倍,因此还需要算其剩余部分给人带来的幸福值。
鉴于这一过程是包含在整个循环的过程中的,可以在计算循环节的时候一并记录。
AC 代码
#include<bits/stdc++.h>
using namespace std;
const int N=100009;
int T,n,k,m,a[N];
int ok[N],ans[N*2],cnt[N*2];
//cnt为循环节内的答案,ans为剩余部分的答案
void input(){
cin>>T;
}
void solve(){
for(int i=0;i<n;i++){//多测清空!!
ok[i]=0;
ans[i]=0;
cnt[i]=0;
}
cin>>n>>k>>m;
for(int i=0;i<n;i++) cin>>a[i];//这里i从0开始是方便后续取模
int tms=m/(n*2);//循环节个数
int rmn=m%(n*2);//剩余部分
for(int i=0;i<n*2;i++){
if(ok[a[i%n]]){
ok[a[i%n]]=0;
if(i<rmn) ans[i%n]++;
cnt[i%n]++;
}
else{
ok[a[i%n]]=1;
}
}
for(int i=0;i<n;i++){
cout<<cnt[i]*tms+ans[i]<<" ";
}
cout<<"\n";
}
int main(){
input();
while(T--){
solve();
}
return 0;
}
本文来自博客园,作者:lemon-cyy,转载请注明原文链接:https://www.cnblogs.com/lemon-cyy/p/19126801

浙公网安备 33010602011771号