ZJU1003 Crashing Balloon - 踩气球

题目大意:

输入两个正整数x,y,判断x和y能否由1到100之间的整数乘积组成,数字不能重复使用。

分析:

想不到很好的方法,一般考虑用搜索来解决。

最初的时候没有考虑到数据范围。稍加分析,x,y最大可以达到100!,大约160位,只能使用高精度运算

搜索核心如下:

void perform(bigNum x,int m)  //对于大数x,用不大于m的整数去试除
{

  if(x等于1) {
    //成功, 标记变量
    return;
  }

  for( p=m ; p>1 ; p-- )  //搜索
    if( p没有用过 && p能整除x ){

      标记p为使用过;
      perform( x/p , p-1 );   //向下递归
      取消p的标记;
    }

}

一次性AC,时间0.04s

=============================================

/*
ZJU1003 Crashing Balloon
搜索+大数除小数
*/

#include <stdio.h>
#include <string.h>
#define clr(a) memset(a,0,sizeof(a))
#define N 205

typedef struct{
    int a[N];
    int len;
}bigNum;

//Vars

bigNum X,Y,One;
int e[N];
int player,achive,uphold;

//Functions

int s2a(char s[],bigNum *b){
    int n,i;
   
    n=strlen(s);
    for(i=0;i<n;i++){
        b->a[n-i-1]=s[i]-'0';
    }
    return n;
}

int input(){
    char x[N+N],y[N+N];
   
    if(scanf("%s%s",x,y)==EOF) return 0;
   
    X.len=s2a(x,&X);
    Y.len=s2a(y,&Y);
   
    return 1;
}

void printb(bigNum b){
    int i;
    for(i=b.len-1;i>=0;i--)
        printf("%d",b.a[i]);
    printf("/n");
}

int cmp(bigNum x,bigNum y){
    int i;
    if(x.len!=y.len) return x.len-y.len;
    for(i=x.len-1;i>=0;i--){
        if(x.a[i]!=y.a[i]) return x.a[i]-y.a[i];
    }
    return 0;
}

void cpy(bigNum *x,bigNum *y){
    int i;
    x->len=y->len;
    for(i=0;i<y->len;i++) x->a[i]=y->a[i];
}

/*
division
    z = x/y
    return x%y
*/
int div(bigNum *x,int y,bigNum *z){
    int i,n,r;
    n=x->len;
   
    for(r=0,i=n-1;i>=0;i--){
        r=r*10+x->a[i];
        z->a[i]=r/y;
        r%=y;
    }
   
    while(n>1&&!z->a[n-1]) n--;
    z->len=n;
   
    return r;
}

//Perform

void perform(bigNum x,int m){
    bigNum y;
    int i,p,r;
   
    if(!cmp(x,One)){
        if(player){
            uphold=1;
            player=0;
            perform(Y,100);
            player=1;
        }
        else{
            achive=1;
        }
        return;
    }
   
    for(p=m;p>1;p--){
        r=div(&x,p,&y);
        if(!e[p]&&!r){
            e[p]=1;
            perform(y,p-1); //next
            e[p]=0;
        }
        if(achive) return;
    }
    return;
}

//Main

int main()
{
    int i,j,k,m,n;
    bigNum Tmp;
   
    One.len=1;
    One.a[0]=1;
   
    while(input()){
        if(cmp(X,Y)>0){
            cpy(&Tmp,&X);cpy(&X,&Y);cpy(&Y,&Tmp);
        }
       
        clr(e);
        player=1; uphold=achive=0;
       
        if(!(X.len>=160||Y.len>160))
            perform(X,100);
       
        if(uphold==achive) printb(Y);
        else printb(X);
    }
   
    return 0;
}

你可能感兴趣的:(struct,ini,input,div)