由于上次徒手撕了大数取模(),所以这次虽然知道了模相关的定理,还是笨笨的又撕了一次大数。。。
剪枝的原理是对于一个数值序列,如果某个模值为R已经出现过了,那么这个R就会反复出现,后面基于这个序列构造的序列就会构造出原来的数值序列构造出的余数序列一样的序列,这样就可以剪枝掉了。。
还有一个。。我又一次出现了似乎都对但是就是WA的场面。。。于是我机智的看了下大神的特判。。。出现0的时候,只有有0才算过。。我是为什么之前认为0*7=7.。。。?。让我死去。。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <queue>
#include <map>
#include <algorithm>
using namespace std;
#define maxn 1010
int tochar[maxn],toint[maxn],que[maxn];
map<string,int>vis;
vector<int>tmp;
int top;
int n,m,c;
void init()
{
memset(tochar,0,sizeof(tochar));
memset(toint,0,sizeof(toint));
for(int i=0;i<10;i++)
tochar[i]=i+'0',toint[i+'0']=i;
for(int i=0;i<6;i++)
tochar[i+10]=i+'A',toint[i+'A']=i+10;
}
void change(int x)
{
top=0;
while(x)
{
que[top++]=x%c;
x/=c;
}
}
void getclear(string &s)
{
for(string::iterator i=s.begin();i!=s.end();)
{
if(*i=='0')
i=s.erase(i);
else break;
}
}
int cmp(string s)
{
getclear(s);
if(s.length()!=top)
return s.length()>top?1:-1;
for(int i=0,j=top-1;i<top;i++,j--)
{
int flag=toint[s[i]]>que[j]?1:-1;
if(toint[s[i]]!=que[j])
return (toint[s[i]]>que[j]?1:-1);
}
return 0;
}
void cal(string &s)
{
int t=cmp(s);
if(t==-1) return;
else if(t==0) {
s="";
return;
}
while(cmp(s)!=-1)
{
tmp.clear();
for(int i=0;i<s.length();i++) tmp.push_back(toint[s[i]]);
for(int i=s.length()-1,j=0;i>=0||j<top;i--,j++)
{
if(j>=top)
{
if(tmp[i]>=0) {
s[i]=tochar[tmp[i]];
//break;
}
else
{
tmp[i-1]-=1;
s[i]=tochar[tmp[i]+c];
}
continue;
}
if(tmp[i]>=que[j])
s[i]=tochar[tmp[i]-que[j]];
else
{
tmp[i-1]-=1;
s[i]=tochar[tmp[i]+c-que[j]];
}
}
getclear(s);
// cout<<"now s is :"<<s<<endl;
// cout<<cmp(s)<<endl;
// system("pause");
}
// cout<<"over"<<endl;
}
string mod(string s)
{
// cout<<"cout:mod:"<<endl;
int t=cmp(s);
if(t==-1) return s;
else if(t==0) return "";
string ret="";
for(int i=0;i<top;i++) ret+=s[i];
for(int i=top-1;i<s.length();i++)
{
// cout<<"ret="<<ret<<endl;
cal(ret);
if(i+1>=s.length()) break;
ret+=s[i+1];
}
// cout<<"over"<<endl;
return ret;
}
class node
{
public:
string s,rem;
node(){}
node(string ss,string re){
s=ss,rem=re;
}
void deal()
{
rem=mod(s);
}
// void debug()
// {
// cout<<"s: "<<s<<" rem: "<<rem<<endl;
// }
}a[17];
queue<node>q;
bool cmp1(node x,node y)
{
return x.s<y.s;
}
int main()
{
//freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
init();
while(T--)
{
vis.clear();
scanf("%d%d%d",&n,&c,&m);
change(n);
while(!q.empty()) q.pop();
for(int i=0;i<m;i++)
{
cin>>a[i].s;
a[i].deal();
}
sort(a,a+m,cmp1);
string ans="";
if(n==0)
{
if(a[0].s=="0") cout<<0<<endl;
else cout<<"give me the bomb please"<<endl;
continue;
}
else if(n==1)
{
int i;
for(i=0;i<m;i++)
if(a[i].s=="0") continue;
else break;
if(i<m) cout<<a[i].s<<endl;
else cout<<"give me the bomb please"<<endl;
continue;
}
q.push(node("",""));
while(!q.empty())
{
string s=q.front().s,rem=q.front().rem;
q.pop();
if(s.length()>500) continue;
for(int i=0;i<m;i++)
{
string tmp=s+a[i].s;
getclear(tmp);
if(tmp.length()==s.length()||tmp.length()==0) continue;
string re=mod(tmp);
getclear(re);
// cout<<"tmp:"<<tmp<<" re:"<<re<<endl;
// system("pause");
if(vis[re]) continue;
vis[re]=1;
if(re==""&&tmp.length()) {
ans=tmp;
break;
}
q.push(node(tmp,re));
}
if(ans!="") break;
}
if(ans!="") cout<<ans<<endl;
else cout<<"give me the bomb please"<<endl;
}
return 0;
}
减肥后。。。。。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <queue>
#include <map>
#include <algorithm>
using namespace std;
#define maxn 1010
int tochar[maxn],toint[maxn],que[maxn];
int vis[5500];
vector<int>tmp;
int top;
int n,m,c;
void init()
{
memset(tochar,0,sizeof(tochar));
memset(toint,0,sizeof(toint));
for(int i=0;i<10;i++)
tochar[i]=i+'0',toint[i+'0']=i;
for(int i=0;i<6;i++)
tochar[i+10]=i+'A',toint[i+'A']=i+10;
}
void getclear(string &s)
{
for(string::iterator i=s.begin();i!=s.end();)
{
if(*i=='0')
i=s.erase(i);
else break;
}
}
int mod(string s)
{
int rem=0;
for(int i=0;i<s.length();i++)
{
rem=(rem*c+toint[s[i]])%n;
}
return rem;
}
string a[17];
queue<string>q;
int main()
{
//freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
init();
while(T--)
{
memset(vis,0,sizeof(vis));
scanf("%d%d%d",&n,&c,&m);
while(!q.empty()) q.pop();
for(int i=0;i<m;i++)
{
cin>>a[i];
}
sort(a,a+m);
string ans="";
if(n==0)
{
if(a[0]=="0") cout<<0<<endl;
else cout<<"give me the bomb please"<<endl;
continue;
}
else if(n==1)
{
int i;
for(i=0;i<m;i++)
if(a[i]=="0") continue;
else break;
if(i<m) cout<<a[i]<<endl;
else cout<<"give me the bomb please"<<endl;
continue;
}
q.push("");
while(!q.empty())
{
string s=q.front();
q.pop();
if(s.length()>500) continue;
for(int i=0;i<m;i++)
{
string tmp=s+a[i];
getclear(tmp);
if(tmp.length()==s.length()||tmp.length()==0) continue;
int re=mod(tmp);
//cout<<"tmp:"<<tmp<<" re:"<<re<<endl;
if(vis[re]) continue;
vis[re]=1;
if(re==0&&tmp.length()) {
ans=tmp;
break;
}
q.push(tmp);
}
if(ans!="") break;
}
if(ans!="") cout<<ans<<endl;
else cout<<"give me the bomb please"<<endl;
}
return 0;
}
Yeah,give me the bomb please