【POI每日一题 #1】BANK-Cash Dispenser

题目链接

拿到这道题 显然第一反应是写暴力

初始思路:找到每个串的公共串 然后再求公共串的PIN码可能性

显然不可做 主要是找公共串过于繁琐

然后逆向思考

因为PIN码只有10000种

所以可以考虑枚举PIN码再验证其是否可行

对于一个动作序列 我们记录它的下一个k(1 <= k <= 9)在哪一位

这样验证一个PIN码时只需按PIN码跳下去(如图)

 1 for(int i = 1; i <= n; i++){
 2         int x; char p[10005]; scanf("%d%s", &x, p);
 3         for(int j = 0; j <= 9; j++) last[j] = -1;
 4         while(x--){
 5             for(int j = 0; j <= 9; j++) next[j][x + 1] = last[j];
 6             last[p[x] - '0'] = x + 1;
 7         }
 8         for(int j = 0; j <= 9; j++) next[j][0] = last[j]; 
 9         for(int j = 0; j <= 9999; j++)
10             flag[j] |= check(j);
11     }
输入并处理

若PIN码未读完跳到-1 则PIN码不可行

 1 bool check(int x){
 2     int last = -1, now;
 3     for(int k = 1, i = 0; k <= 4; k++){
 4         now = x % 10; x /= 10;
 5         if(last == now) continue ;
 6         i = next[now][i]; last = now;
 7         if(i == -1) return 1;
 8     }
 9     return 0;
10 }
OP: check

 

时间复杂度 : O(t10+10000n)

猜你喜欢

转载自www.cnblogs.com/hjmmm/p/9185203.html