[CSP-S 2023] 密码锁

题目描述

小 Y 有一把五个拨圈的密码锁。如图所示,每个拨圈上是从 00 到 99 的数字。每个拨圈都是从 00 到 99 的循环,即 99 拨动一个位置后可以变成 00 或 88,

因为校园里比较安全,小 Y 采用的锁车方式是:从正确密码开始,随机转动密码锁仅一次;每次都是以某个幅度仅转动一个拨圈或者同时转动两个相邻的拨圈。

当小 Y 选择同时转动两个相邻拨圈时,两个拨圈转动的幅度相同,即小 Y 可以将密码锁从 0  0  1  1  500115 转成 1  1  1  1  511115,但不会转成 1  2  1  1  512115。

时间久了,小 Y 也担心这么锁车的安全性,所以小 Y 记下了自己锁车后密码锁的 nn 个状态,注意这 nn 个状态都不是正确密码。

为了检验这么锁车的安全性,小 Y 有多少种可能的正确密码,使得每个正确密码都能够按照他所采用的锁车方式产生锁车后密码锁的全部 nn 个状态。

输入格式

输入的第一行包含一个正整数 nn,表示锁车后密码锁的状态数。

接下来 nn 行每行包含五个整数,表示一个密码锁的状态。

输出格式

输出一行包含一个整数,表示密码锁的这 nn 个状态按照给定的锁车方式能对应多少种正确密码。

样例 #1

样例输入 #1

1
0 0 1 1 5

Copy

样例输出 #1

81

Copy

提示

【样例 1 解释】

一共有 8181 种可能的方案。

其中转动一个拨圈的方案有 4545 种,转动两个拨圈的方案有 3636 种。

【样例 2】

见选手目录下的 lock/lock2.in 与 lock/lock2.ans。

【数据范围】

对于所有测试数据有:1≤n≤81≤n≤8。

测试点n≤n≤特殊性质
1∼31∼311
4∼54∼522
6∼86∼888A
9∼109∼10

特殊性质 A:保证所有正确密码都可以通过仅转动一个拨圈得到测试数据给出的 nn 个状态。

非官方数据

思路

能通过转动一个拨圈任意幅度,或者两个拨圈相同幅度,求能达到 n 个状态的可能正确的密码方案数。

注意到 n≤10,且拨圈只有五个,我们可以枚举转动幅度计数,最终状态是正确答案当且仅当它能通过 n 个状态转移而来。

 

#include<bits/stdc++.h>
using namespace std;
int n,aa,f[11][11][11][11][11],mod=10,a,b,c,d,e;
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a>>b>>c>>d>>e;
		for(int j=1;j<=9;j++){
			f[(a+j)%mod][b][c][d][e]++;
			f[a][(b+j)%mod][c][d][e]++;
			f[a][b][(c+j)%mod][d][e]++;
			f[a][b][c][(d+j)%mod][e]++;
			f[a][b][c][d][(e+j)%mod]++;
			f[(a+j)%mod][(b+j)%mod][c][d][e]++;
			f[a][(b+j)%mod][(c+j)%mod][d][e]++;
			f[a][b][(c+j)%mod][(d+j)%mod][e]++;
			f[a][b][c][(d+j)%mod][(e+j)%mod]++;
		}
	}
	for(int i=0;i<=9;i++){
	    for(int j=0;j<=9;j++){
	        for(int k=0;k<=9;k++){
	            for(int u=0;u<=9;u++){
	                for(int v=0;v<=9;v++){
						if(f[i][j][k][u][v]==n) aa++;
					}
				}
			}
		}   
	}     
	cout<<aa;
	return 0;
}

  • 24
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值