首页 > 其他分享 >[题解]P9752 [CSP-S 2023] 密码锁

[题解]P9752 [CSP-S 2023] 密码锁

时间:2023-10-22 22:46:20浏览次数:42  
标签:P9752 错误 int 题解 return 密码 dist 密码锁 define

这次 CCF 的行为过于迷惑了。

思路

首先发现只会有 \(10^5\) 种密码,考虑枚举它们,然后去 check

假设当前密码是:\(p_1,p_2,p_3,p_4,p_5\)。如果它能从对于所有 \(1 \sim n\) 种错误的密码按照题目所述的操作得到,那么此密码就是合法的。

假设我们现在判断当前密码能否由第 \(i\) 种错误密码得到。

不难发现如果错误的位数为 \(0\) 或者大于 \(2\),此密码一定不合法。因为如果为 \(0\),表示这是错误的密码;如果大于 \(2\),表示不能通过一次操作得到。

如果错误的位数为 \(1\) 一定合法,因为我们可以只转动错误的一位来得到。

错误位数为 \(2\) 的情况,我们需要考虑错误的两位是否相邻,如果不相邻一定不行。

其次判断这两个错误的位置能否通过转动相同幅度得到。这里我是用了一个 \(dist(i,j)\) 来计算从 \(i\) 到 \(j\) 需要转动几次,当然这里需要计算往上转和往下转两种情况。

code

#include <bits/stdc++.h>
#define fst first
#define snd second
#define re register
#define int long long

using namespace std;

typedef pair<int,int> pii;
const int N = 25;
int n,ans;
int p[N];
int t[N] = {0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9};//破环成链,便于计算 dist 
int arr[N][N];

inline int read(){
    int r = 0,w = 1;
    char c = getchar();
    while (c < '0' || c > '9'){
        if (c == '-') w = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9'){
        r = (r << 1) + (r << 3) + (c ^ 48);
        c = getchar();
    }
    return r * w;
}

inline pii dist(int x,int y){
    pii res;
    for (re int i = x;t[i] != y;i++) res.fst++;
    for (re int i = 10 + x;t[i] != y;i--) res.snd++;
    return res;
}

inline bool check(int x){
    vector<int> v;
    for (re int i = 1;i <= 5;i++){
        if (p[i] != arr[x][i]) v.push_back(i);
    }
    int sz = v.size();
    if (!sz || sz > 2) return false;
    if (sz == 1) return true;
    if (v[1] - v[0] == 1){
        pii a = dist(p[v[0]],arr[x][v[0]]);
        pii b = dist(p[v[1]],arr[x][v[1]]);
        if (a.fst == b.fst || a.snd == b.snd) return true;
    }
    return false;
}

inline void dfs(int u){
    if (u == 6){
        for (re int i = 1;i <= n;i++){
            if (!check(i)) return;
        }
        ans++;
        return;
    }
    for (re int i = 0;i <= 9;i++){
        p[u] = i;
        dfs(u + 1);
    }
}

signed main(){
    n = read();
    for (re int i = 1;i <= n;i++){
        for (re int j = 1;j <= 5;j++) arr[i][j] = read();
    }
    dfs(1);
    printf("%lld",ans);
    return 0;
}

最后

不要脸的放上我的游记

尽管没发挥好,但是来年再战。

CSP-2024 S RP++。

标签:P9752,错误,int,题解,return,密码,dist,密码锁,define
From: https://www.cnblogs.com/WaterSun/p/P9752.html

相关文章

  • 洛谷-P9779 题解
    正文对于每个选择题,都有两种状态,因此总状态数为\(2^n\)。请注意初始所有选择题都不选也是一个状态,不计入贡献,因此答案为\(2^n-1\)。代码:#include<iostream>usingnamespacestd;intmain(){longlongn;cin>>n;cout<<(1<<n)-1;}提交记录。......
  • CSP-S 2023 题解
    CSP-S2023题解密码锁发现总状态数只有\(10^5\)个,枚举\(O(n)\)暴力判断即可,复杂度\(O(10^5n)\)。或者每一个状态只对应了\(81\)个状态,枚出来,取交集即可,复杂度\(O(81n)\)。消消乐好的,来一波抽象做法QwQ我看到这道题的第一眼:这不就是QOJ6504Flower'sLand2吗......
  • 洛谷题解 | AT_abc321_c Primes on Interval
    目录题目翻译题目描述输入格式输出格式样例#1样例输入#1样例输出#1样例#2样例输入#2样例输出#2样例#3样例输入#3样例输出#3题目简化题目思路AC代码题目翻译【题目描述】你决定用素数定理来做一个调查.众所周知,素数又被称为质数,其含义就是除了数字一和本身之外不能......
  • [ABC234E] Arithmetic Number 题解
    题目传送门一道枚举题。暴力枚举数字位数、首位、等差数列的公差即可。注意公差的枚举范围,并且需要看看末尾合不合法。顺便提一下,我是用字符串存储枚举的数字的,所以写了一个check函数代替大于号。Code#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;......
  • [ABC231E] Minimal payments 题解
    题目传送门一道贪心题。感觉很裸啊,模拟赛时随便乱写了个暴力递归就能过。每次找最接近钱数\(x\)的面额\(num\),如果比钱数少那么答案为剩下\(x\bmodnum\)钱数的答案加上\(x\divnum\)。否则答案则为剩下\(num-x\)钱数的答案加上\(1\)。Code#include<bits/stdc++.h......
  • ABC323D题解
    ABC323DMergeSlimes题目简述小A有\(N\)种橡皮泥。对于第\(i\)种橡皮泥,它的大小为\(S_i\)且一共有\(C_i\)个。小A可以合成两个大小相同的橡皮泥,若这两个橡皮泥大小为\(X\),则新和成的橡皮泥大小为\(2X\)。小A想知道,在进行若干次合成后(有可能\(0\)次),他能获得......
  • P9754 [CSP-S 2023] 结构体 题解
    前言在考场上调了2h+还没调出来,并且T4也没来得及做。希望看到这段文字的你能避免这样的悲剧。正文题目要求动态创建类型,于是我用结构体代表一个struct(禁止套娃),要新建就new出来一个。(最后也没delete)structObj{typnamtnam;lllen,align;std::map<std:......
  • CSP-S 2023 题解
    expect:\(100+100+65+25=290\)真实:\(100+85+0+15=205\),rk62感觉自己考的好烂好烂好烂T4这么简单竟然想不出来,感觉如果自己不被T4吓到,全做出来其实有望365+?今年CSP-S怎么这么简单吓得我不敢做了T1暴力T2考场做法:设\(lst_i\)表示\(a_i=a_{lst_i}\)并且\((......
  • pip安装慢问题解决
     一、永久修改pip软件安装默认源使用pipconfigsetglobal.index-url来直接指定下载源的URL,这样就不用手动修改配置文件了pipconfigsetglobal.index-urlhttps://pypi.tuna.tsinghua.edu.cn/simple以下是国内互联网常用的pypi安装源URL,在国内互联网下载的速度非常快......
  • CSP-S2023 题解
    更好的阅读体验CSP-S2023游记密码锁(lock)\(10^5\)枚举所有可能答案,然后判断。代码#include<bits/stdc++.h>intn;inta[13][7],b[7];boolcheck(inti){ intcnt=0; for(intj=1;j<=5;j++)cnt+=(a[i][j]!=b[j]); if(cnt==1)returntrue; else......