初始状态下,这 2026 盏路灯均处于高能耗的“全亮模式”。为了评估系统在极端工况下的响应能力,该局的主控系统需要针对理论上存在的所有开关组合进行全状态遍历推演。
只是,受限于底层硬件的物理特性,主控系统必须严格按照“双向交替”的规则执行操作:
- 第奇数次指令(第 1,3,5… 次):系统需选定一盏路灯 �(1≤�≤2026),将该路灯及其右侧(后方)所有路灯的开关状态进行翻转(亮变暗,暗变亮)。
- 第偶数次指令(第 2,4,6… 次):系统需选定一盏路灯 �,将该路灯及其左侧(前方)所有路灯的开关状态进行翻转。
对于 2026 盏路灯,共存在 22026 种不同的明暗状态组合,每一种状态都必定能被抵达。针对每一种特定的状态,都存在一个从初始“全亮”状态到达该状态所需的最少指令操作次数(无论有多少种不同的操作序列可以到达该状态,仅以步数最少的为准)。
注意:初始的“全亮”状态也包含在这 22026 种组合中,且到达该状态的最少操作次数记为 0 次。
现在,请你计算出这全部 22026 种状态对应的最少操作次数的累加总和。由于总和可能很大,请将结果对 998244353 取模后输出。
输入格式
无
输出格式
这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
输入输出样例 #1
输入 #1
输出 #1
题目链接
解题思路
- 因为求最小操作次数,等价于求最短路径,所以小数据可以用bfs
- 再根据小数据画出图像为“j”型增长,那么一定与幂函数有关
再观察得每个答案都能被n整除,且除完之后特别 “整”、特别 “好看” - 最后总结得出n*2^(n-1) ,由于是2的次幂所以其实可以不用快速幂,用左移即可
代码实现
//n*2^(n-1) |
//根据小数据画出图像为“j”型增长,那么一定与幂函数有关 |
//再观察得每个答案都能被n整除,且除完之后特别 “整”、特别 “好看” |
/* |
#include |
using namespace std; |
using ll=long long; |
const int p=998244353; |
ll qmi(ll a,ll b){ |
ll res=1; |
while(b){ |
if(b&1)res=res*a%p; |
a=a*a%p,b>>=1; |
} |
return res%p; |
} |
int main() |
{ |
ll n=2026; |
ll ans=n*qmi(2,n-1)%p; |
cout< |
return 0; |
} |
*/ |
//状态空间bfs搞定小数据,再用数学归纳法推出结论 |
#include |
using namespace std; |
const int mod=998244353; |
queueq; |
unordered_mapdis; |
int n; |
//翻转区间[l,r] |
string flip(string s, int l, int r) { |
for (int i=l;i<=r;i++) { |
s[i]=s[i]=='1'?'0':'1'; |
} |
return s; |
} |
void bfs(string st){ |
dis[st]=0; |
q.push(st); |
while(q.size()){ |
auto t=q.front();q.pop(); |
int step=dis[t]; //当前是第几步 |
//当前偶数,下一步奇数次操作:翻转i~n-1 |
if(step%2==0){ |
for(int i=0;i |
string nt=flip(t,i,n-1); |
//dis[nt] 会自动插入不存在的键->破坏 BFS |
//dis.count(nt) 只查询,不插入->安全 |
if(!dis.count(nt)){ |
dis[nt]=dis[t]+1; |
q.push(nt); |
} |
} |
}else { //当前奇数,下一步偶数次操作:翻转0~i |
for(int i=0;i |
string nt=flip(t,0,i); |
if(!dis.count(nt)){ |
dis[nt]=dis[t]+1; |
q.push(nt); |
} |
} |
} |
} |
} |
int main(){ |
cin>>n; |
string st; |
for(int i=0;i |
bfs(st); |
long long ans=0; |
for (auto t:dis){ |
int d=t.second; |
ans=(ans+d)%mod; |
} |
cout< |
return 0; |
} |