链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
题目描述
There is a combination lock with n (1≤n≤5) digits , each digit being between 0∼9. For each digit, turning it clockwise by one position will change the digit from x to x+1 mod 10. For example, 0 becomes 1, 1 becomes 2, and 9 turns into 0. Turning it counterclockwise does the opposite, changing the digit to x+9 mod 10.
Little Cyan Fish has locked the secrets of the China Clattering Processing Contest (CCPC) with this combination lock. Every day, to secure the secrets, Little Cyan Fish scrambles the combination by repeating the following operations for some number of times: turning an interval [l,r] (1≤l≤r≤n) of digits by one position, each turn accompanied by a distinct ``tada'' sound.
As Big Black Fish, who is secretly positioned next to Little Cyan Fish, you aim to steal the secrets for a reward. You eavesdrop on Little Cyan Fish's locking process daily, recording the number of ``tada'' sounds --- which is the number of operations, and then inspect the digits on the lock in the dead of night.
You have collected m pieces of information, and you need to determine whether the information collected uniquely identifies the correct combination.
输入描述:
The input consists of multiple test cases. The first line contains T (1≤T≤1000), the number of test cases. For each test case, the first line contains two numbers, n,m (1≤n≤5,1≤m≤50), separated by a space. The next m lines contain a string of n digits sis_isi and an integer ti (0≤ti≤50), indicating the combination displayed is si, resulting from ti operations on the correct combination. The digit string and the number are separated by a space. It is guaranteed that for all T cases.
输出描述:
For each test case: * If there is a unique solution, output a line with the n-digit combination. * If there are multiple solutions, output a line with the string MANY. * If there is no solution, indicating an error in the records, output a line with the string IMPOSSIBLE.
示例1
输入
3
3 3
003 1
003 3
025 1
3 2
000 1
999 1
1 2
0 0
1 0
输出
014
MANY
IMPOSSIBLE
说明
题目大意:给你一个长度为 n 的 密码锁 和 m 条消息,每条消息有 字符串 s 和 数字 t ,s 是密码锁上的数,t 是 转密码锁 t 下能转到正确密码。如果正确密码只有一个输出其值,如果没有正确密码输出"IMPOSSIBLE",如果正确密码有多个输出"MANY"。
思路:知道 n 后 可以得出 正确密码的范围是 0 ~ ,用一个数组 vis 来标记这个数是否是正确密码。每输入一对 s ,t ,就跑一遍 0 ~
,看0 ~
能不能转 t 下跑到 s ,不能的话标记掉。最后处理完后,再跑一遍0 ~
,看有几个数没被标记过,根据数量输出答案即可。(具体操作请看代码)
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int n,m;
int vis[1000005];
int check(int a,int b,int t,int cnt){//求 a 到 b 最少操作步数
if(cnt>n) return 0;
int x=a%10,y=b%10,z=(x-y+10)%10,ans=100000;
ans=min(ans,max((int)0,min(z,z-t))+check(a/10,b/10,z,cnt+1));
z=(y-x+10)%10;
ans=min(ans,max((int)0,min(z,z+t))+check(a/10,b/10,-z,cnt+1));
return ans;
}
signed main()
{
IOS
int _;
cin >> _;
while(_--){
cin >> n >> m;
int maxn=pow(10,n)-1;//正确密码的最大范围
fill(vis,vis+maxn+1,0);//将标记数组初始化为 1
for(int i=1;i<=m;i++){
int s,t;
cin >> s >> t;
for(int j=0;j<=maxn;j++){
if(vis[j]) continue;
if(check(j,s,0,1)>t || (n==1 && (j+s+t)%2!=0) || (t==1 && s==j)) vis[j]=1;
/* check(j,s,0,1) 是 j 到 s 的 最少转动次数,若比 t 大则不可能是正确密码,
当 n = 1 时,j + t + 2*k = s (k为整数)时满足正确密码,所以在 n = 1 的情况下满足正确密码的条件是 (j+s+t)%2=0,
当 s = j 时,t至少大于等于 2 才能使 j 转动 t 次后回到 s ,即 t = 1 时不满足正确密码。
*/
}
}
int ans=0,cnt=0;
for(int i=0;i<=maxn;i++){//还未标记的都是正确密码
if(!vis[i]) cnt++,ans=i;
}
if(cnt==1){
int tmp=ans;
string str="";
while(tmp>0){
str=char(tmp%10+'0')+str;
tmp/=10;
n--;
}
while(n>0) str='0'+str,n--;
cout << str << endl;
}else if(cnt==0) cout << "IMPOSSIBLE" << endl;
else cout << "MANY" << endl;
}
return 0;
}