【八中测试】平分石子

来源:互联网 发布:unity 编写js文件 编辑:程序博客网 时间:2024/05/01 14:51

3524: 平分石子

时间限制: 1 Sec
内存限制: 128 MB

题目描述

有3堆石子,初始时数量分别有A,B,C颗。每次操作是针对某两堆,设这两堆的当前石子数量为X,Y且X < Y. 然后从数量多的一堆中取出X颗石子放入数量少的一堆,使数量少的一堆加倍。操作后两堆石子的数量为:X+X, Y-X
问:经过任意多次的操作,能否使得3堆石子的数量相等?

输入

第1行:3个整数A,B,C (1<=A,B,C<=1000)

输出

第1行:如果可以相等,输出”possible”,否则输出”impossible”

样例输入

10 15 35

样例输出

possible

提示

第1次操作:10, (15,35) => 10, 20, 30

第2次操作:20, (10,30) => 20, 20, 20

来源

【思路】

开始看到此题的我,第一感觉就是模拟,找规律,但是后面却被卡死了……虽说在模拟的途中,我也曾经想过搜索,但似乎并没有什么卵用 -_-,还是没有用搜索的方法。好啦,不多说了,下面我就讲讲深搜的思路吧。
其实,深搜也不难啊,就是一个一个的枚举,但是注意要记忆化,与一个特判,这样可以节省很多时间。
①深搜(常规版)

#include<cstdio>#include<algorithm>using namespace std;bool dis[3001][3001],flag;void dfs(int A,int B,int C){    if(A==B&&B==C)    {        flag=1;        return ;    }    if(dis[A][B]||!A||!B||!C) return ;    dis[A][B]=1;    if(A>B) dfs(A-B,B*2,C);    else dfs(A*2,B-A,C);    if(flag)        return ;    if(A>C) dfs(A-C,B,C*2);    else dfs(A*2,B,C-A);    if(flag)        return ;    if(B>C) dfs(A,B-C,C*2);    else dfs(A,B*2,C-B);    if(flag)        return ;}int main(){    //freopen("pile.in","r",stdin);    //freopen("pile.out","w",stdout);    int A,B,C;    scanf("%d %d %d",&A,&B,&C);    if((A+B+C)%3==0) dfs(A,B,C);    if(!flag) printf("impossible");    else printf("possible");}

②深搜(大神版)

#include<cstdio>#define MAXN 3000bool memo[MAXN+1][MAXN+1];void dfs(int s[]) {    int t[3];    if(memo[s[0]][s[1]])return;    memo[s[0]][s[1]]=true;//记忆化    for(int i=0;i<3;i++)        for(int j=0;j<3;j++)             if(s[i]<s[j])//神奇之地            {                t[0]=s[i]*2;                t[1]=s[j]-s[i];                t[2]=s[0+1+2-i-j];                dfs(t);            } }int main(){    //freopen("pile.in","r",stdin);    //freopen("pile.out","w",stdout);    int a[3], sum;    scanf("%d%d%d", &a[0], &a[1], &a[2]);    sum = a[0]+a[1]+a[2];    if( sum % 3 != 0) {//特判        printf("impossible\n");        return 0;    }    dfs(a);    if(memo[sum/3][sum/3])        printf("possible\n");    else        printf("impossible\n");    return 0;}
原创粉丝点击