HDU 1226 【搜索 + 大数取模】

由于上次徒手撕了大数取模(再见),所以这次虽然知道了模相关的定理,还是笨笨的又撕了一次大数。。。

剪枝的原理是对于一个数值序列,如果某个模值为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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值