您的位置:首页 > 其它

A very hard Aoshu problem

2016-08-04 00:24 176 查看
[b]A very hard Aoshu problem[/b]

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4403

[b]DFS[/b]

这几天集训,一天也就写个4题,被虐哭QAQ。回寝室后游少说解搜索就大胆搜,最后剪个枝就好了Orz,然后我就尝试解这题(剪枝要风骚)。我先枚举等号的位置equ,然后搜索加号add的位置,然后主要的剪枝:如果等号左边运算后小于等号右边各个位上的数的和,那么后面的肯定不满足条件,右边同理。最后要小心爆int,这里吃了很多WA

代码如下:

#include<cstdio>
#include<cstring>
#define LL long long
using namespace std;
char str[16];
LL pre[16];
bool add[16];
LL sum;
LL len;
LL equ;
void dfs(int index);
LL left();
LL right();
int main(void){
//freopen("in.txt","r",stdin);
//freopen("out_1.txt","w",stdout);
scanf("%s",str);
while(strcmp(str,"END")){
len=strlen(str);
memset(pre,0,sizeof(pre));
pre[0]=str[0]-'0';
for(int i=1;i<len;++i)
pre[i]=pre[i-1]+str[i]-'0';
sum=0;
for(equ=1;equ<len;++equ){
memset(add,0,sizeof(add));
dfs(1);
}
printf("%I64d\n",sum);
scanf("%s",str);
}
}
LL left(){
LL s=0;
LL t=0;
for(LL i=0;i!=equ;++i){
if(!add[i]){
t=t*10+str[i]-'0';
}else{
s+=t;
t=str[i]-'0';
}
}
s+=t;
return s;
}
LL right(){
LL s=0;
LL t=0;
for(LL i=equ;i<len;++i){
if(!add[i]){
t=t*10+str[i]-'0';
}else{
s+=t;
t=str[i]-'0';
}
}
s+=t;
return s;
}
void dfs(int index){
LL l=left();
LL r=right();
if(l==r){
sum++;
}else{ //剪枝
if(l<pre[len-1]-pre[equ-1])
return;
if(r<pre[equ-1])
return;
}
if(index>=len)
return;
for(LL i=index;i<len;++i){
if(i!=equ){
add[i]=1;
dfs(i+1);
add[i]=0;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: