把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

【2019.7.20 NOIP模拟赛 T1】A(A)(暴搜)

打表+暴搜

这道题目,显然是需要打表的,不过打表的方式可以有很多。

我是打了两个表,分别表示每个数字所需的火柴棒根数以及从一个数字到另一个数字,除了需要去除或加入的火柴棒外,至少需要几根火柴棒

然后我们就可以暴搜了,大体就是枚举等式左边两个数每一位的值,并枚举中间的运算符是\(+\)还是\(-\),然后计算出等式右边的值,判断是否合法。

中间过程可以加上一些剪枝。

注意当火柴棒从某一位移到另一位时,我们可以规定,去除火柴棒需要算步数,加入火柴棒则无需算步数,这样就可以避免重复了。

具体实现有一些小细节,可以参考代码

代码

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 20
#define Gmin(x,y) (x>(y)&&(x=(y)))
using namespace std;
const int q[10]={6,2,5,5,4,5,6,3,7,6};//打表
const int p[10][10]=//打表
{
	{0,0,1,1,1,1,1,0,0,1},{0,0,1,0,0,1,1,0,0,0},{1,1,0,1,2,2,1,1,0,1},{1,0,1,0,1,1,1,0,0,0},{1,0,2,1,0,1,1,1,0,0},
	{1,1,2,1,1,0,0,1,0,0},{1,1,1,1,1,0,0,1,0,1},{0,0,1,0,1,1,1,0,0,0},{0,0,0,0,0,0,0,0,0,0},{1,0,1,0,0,0,1,0,0,0}
};
int n,a[N+5],b[N+5];string s;
class Dfser//暴搜
{
	private:
		int ans;
		I void Calc(CI x,CI y,RI v,CI w)//计算,判断答案是否合法
		{
			if(w<0) return;RI i,t,k=0,t1=0,t2=0;for(i=x;i^n;++i) t1+=b[i];
			t=w;W(t2+=q[t%10],++k,t/=10);if(k>n-x||(t1+y)^t2) return;
			for(t=w,i=n-1;i>=x;--i)
			{
				if(i^(n-1)&&!t) return;
				v+=p[a[i]][t%10]+max(b[i]-q[t%10],0),t/=10;
			}Gmin(ans,v);
		}
		I void dfs(CI x,CI y,CI v,CI sv,CI op,CI tot)//暴搜,枚举每一位的值和运算符
		{
			if(abs(y)>5*(n-x)||ans<=v) return;if(s[x]=='=') return Calc(x+1,y,v,tot+sv*op);
			if(s[x]=='+') dfs(x+1,y,v,0,1,tot+sv*op),dfs(x+1,y+1,v+1,0,-1,tot+sv*op);
			else if(s[x]=='-') dfs(x+1,y,v,0,-1,tot+sv*op),dfs(x+1,y-1,v,0,1,tot+sv*op);
			else
			{
				dfs(x+1,y,v,sv*10+a[x],op,tot);
				for(RI i=!((x&&isdigit(s[x-1]))||!isdigit(s[x+1]));i<=9;++i)
					a[x]^i&&(dfs(x+1,y+b[x]-q[i],v+p[a[x]][i]+max(b[x]-q[i],0),sv*10+i,op,tot),0);
			}
		}
	public:
		I void Solve() {ans=1e9,dfs(0,0,0,0,1,0),ans==1e9?puts("-1"):printf("%d",ans);}
}D;
int main()
{
	freopen("A.in","r",stdin),freopen("A.out","w",stdout);
	cin>>s,n=s.length(),s+="@";for(RI i=0;i^n;++i) b[i]=q[a[i]=s[i]&15];
	return D.Solve(),0;
}
posted @ 2019-07-31 09:44  TheLostWeak  阅读(179)  评论(0编辑  收藏  举报