• 【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;
    }
    
  • 相关阅读:
    Git代码行数统计命令
    JPA访问数据库的几种方式
    爱码小士丨代码一敲十年,收入虽高前途摇摆
    “肉瘾”女孩从软件测试工程师到主管的成长感悟
    华为测试大牛Python+Django接口自动化怎么写的?
    携程大牛的单元测试是怎么样写的?
    Jmeter参数的AES加密使用
    弄啥嘞?热爱你的Bug
    “进腾讯工作一个月,我想辞职了”
    我在华为,软件测试人员在工作中如何运用Linux?
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Contest20190720T1.html
Copyright © 2020-2023  润新知