【搜索】 HDU 1226 超级密码
前辈说
A%M==B%M (A!=B)
有(A*C+K)%M==(B*C+K)%M;
所以在某个余数出现过后一个就不需要考虑还是该余数的数了
一共有5000个余数 当余数为0时为整除
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <string> #include <iostream> #include <algorithm> #include <sstream> #include <math.h> using namespace std; #include <queue> #include <stack> #include <vector> #include <deque> #include <set> #include <map> #define cler(arr, val) memset(arr, val, sizeof(arr)) #define IN freopen ("in.txt" , "r" , stdin); #define OUT freopen ("out.txt" , "w" , stdout); typedef long long LL; const int MAXN = 211;//点数的最大值 const int MAXM = 20006;//边数的最大值 const int INF = 1101521204; const int mod = 10000007; char in[33],ans[555]; int ini[33],re[5100],pre[5100]; int t,n,c,m,cnt; void find(int x) { if(pre[x]!=-1) find(pre[x]); ans[cnt++]=re[x]; } queue<int>q; void solve() { cler(re,-1); sort(ini,ini+m); if(n==0) { if(ini[0]==0) printf("0\n"); else printf("give me the bomb please\n"); return ; } while(!q.empty()) q.pop(); for(int i=0;i<m;i++) { if(ini[i]) { q.push(ini[i]%n); if(re[ini[i]%n]==-1) //re存上一个的数字 pre表示表头 pre[ini[i]%n]=-1,re[ini[i]%n]=ini[i]; } } while(!q.empty()) { int x=q.front();q.pop(); if(x==0) break; for(int i=0;i<m;i++) { int y=(x*c+ini[i])%n; if(re[y]==-1) { pre[y]=x; re[y]=ini[i]; q.push(y); } } } if(re[0]==-1){ printf("give me the bomb please\n"); return ; } cnt = 0; find(0); if(cnt>500){ printf("give me the bomb please\n"); return ; } for(int i=0;i<cnt;i++){ if(ans[i]<=9) printf("%d",ans[i]); else printf("%c",ans[i]-10+'A'); }printf("\n"); } int main() { // IN; scanf("%d",&t); while(t--) { scanf("%d%d%d ",&n,&c,&m); for(int i=0; i<m; i++) { scanf("%c ",&in[i]); if(in[i]<='9'&&in[i]>='0') ini[i]=in[i]-'0'; else ini[i]=in[i]-'A'+10; } solve(); } }