蓝桥杯测试


一步之遥

从昏迷中醒来,小明发现自己被关在X星球的废矿车里。
矿车停在平直的废弃的轨道上。
他的面前是两个按钮,分别写着“F”和“B”。

小明突然记起来,这两个按钮可以控制矿车在轨道上前进和后退。
按F,会前进97米。按B会后退127米。
透过昏暗的灯光,小明看到自己前方1米远正好有个监控探头。
他必须设法使得矿车正好停在摄像头的下方,才有机会争取同伴的援助。
或许,通过多次操作F和B可以办到。

矿车上的动力已经不太足,黄色的警示灯在默默闪烁...
每次进行 F 或 B 操作都会消耗一定的能量。
小明飞快地计算,至少要多少次操作,才能把矿车准确地停在前方1米远的地方。

请填写为了达成目标,最少需要操作的次数。

注意,需要提交的是一个整数,不要填写任何无关内容(比如:解释说明等)

 

 

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
int main(void)
{
    int Min = 0xFFFFFFF;
    for(int i=0;i<=1000;i++)
        for(int j=0;j<=1000;j++) 
          if(97*i-127*j==1 && i+j<Min) 
          {
              Min = i + j;
          }
    cout << Min ;
    return 0;
 } 

 


凑平方数

把0~9这10个数字,分成多个组,每个组恰好是一个平方数,这是能够办到的。
比如:0, 36, 5948721

再比如:
1098524736
1, 25, 6390784
0, 4, 289, 15376
等等...

注意,0可以作为独立的数字,但不能作为多位数字的开始。
分组时,必须用完所有的数字,不能重复,不能遗漏。

如果不计较小组内数据的先后顺序,请问有多少种不同的分组方案?

注意:需要提交的是一个整数,不要填写多余内容。

 

 这个方法是参考网上的方法,思路是首先使用全排列得到各种可能的组合,然后对于一个特定的序列组合,找到可能的平方数组合,为了防止重复,这里规定一个序列组合中的平方数只能从小到大进行排列。

#include<iostream>
#include<cstdio>
#include<map>
#include<algorithm>
typedef long long LL;
using namespace std;

int s[10]={0,1,2,3,4,5,6,7,8,9};
int ans; 
map<LL,int>mp;

void dfs(LL ss,int x)
{
    if(x==10)
    {
        cout << ans << endl;
        ans++;
        return ; 
    }
    if(s[x]==0)
    {
        if(x==0) dfs(0,x+1);
        return ;
    }
    LL sum=0;
    for(int i=x;i<10;i++)
    {
        sum=sum*10+s[i];
        if(sum>ss && mp[sum]) dfs(sum,i+1);
    }
}
int main(void)
{
    for(LL i=0;i<=500000;i++) mp[i*i]=1;
    do{
        dfs(-1,0);
    }while(next_permutation(s,s+10));
    cout << ans << endl;
    return 0;
}

这是我自己重新写了一下的方法,但是一直结果不正确,后来终于发现了原因。

#include<map>
#include<iostream>
#include<cstdio>
#include<algorithm> 
using namespace std;

typedef long long LL;

map<LL,int>mp;
int a[10],sum=0;

void DFS(LL pre,int cur)
{
    if(cur==10)
    {
        sum++;
        return ;
    }
    if(a[cur]==0 )
    {  
        if(cur==0) DFS(0,cur+1); 
        return ; 
    }
    else 
    {
        LL s = 0;
        for(int i=cur;i<10;i++)
        {
            s=s*10+a[i];
            if(s>pre && mp[s]) DFS(s,i+1);    
        }    
    }
}

int main(void)
{    
    for(int i=0;i<10;i++) a[i]=i;
    for(int i=0;i<=500000;i++) mp[i*i]=1;
    do{
        DFS(-1,0);
    }while(next_permutation(a,a+10));
    printf("sum = %d\n",sum);
    return 0;
}
//eg.这里再初始化的时候i*i首先是保存为int,然后再转换为long long,因此这里越界了,
//应该写成for(long long i=0;i<=500000;i++) mp[i*i]=1;

 

这个是我的方法,首先也是全排列,然后对于每一个序列,找到他的所有的平方数的组合,注意此时不需要进行从小到大的排列。然后把每一个序列的平方数组合情况放到一个set中,这样就能够实现自动的排序,然后再使用一个集合set,这样就可以实现去除重复。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<set>
#include<algorithm>
const int eps = 10e-8;
using namespace std;
int a[10];
set<set<long long> >se;
set<long long>Sqrtn;
void DFS(int i,long long b[],int n)
{
    if(i==10)
    {
        set<long long> s;
        for(int i=0;i<n;i++) s.insert(b[i]);
        se.insert(s); 
        return ;
    }
    long long s = 0;
    int first = 1;
    while(i<=9)
    {
        s=s*10+a[i];
        if(a[i]==0 && first==1)
        {
            b[n]=0;
            DFS(i+1,b,n+1);
            break;
        }
        first = 0;
        //直接开放计算 
        long long sqrtn = (long long )(sqrt(s*1.0)+0.5);
        if(sqrtn * sqrtn == s) 
        {
            b[n]=s;
            DFS(i+1,b,n+1);
        }
         
        /*
        使用集合计算 
        if(Sqrtn.find(s) != Sqrtn.end())
        {
            b[n]=s;
            DFS(i+1,b,n+1);
        }
        */
        i++;
    }
}
int main(void)
{
    long long b[10];
    for(int i=0;i<10;i++) a[i]=i;
    for(long long i=0;i<=100000;i++) Sqrtn.insert(i*i); 
    
    do
    {
        //for(int i=0;i<10;i++) printf("%d",a[i]);
        //printf("\n");
        DFS(0,b,0);
    }while(next_permutation(a,a+10));
    
    for(set<set<long long> >::iterator it = se.begin();it!=se.end();it++)
    {
        set<long long> s = *it;
        for(set<long long >::iterator x=s.begin();x!=s.end();x++)
        {
            printf("%lld    ",*x);
        }
        printf("\n");
    }
    cout << "sum = " << se.size()<<endl;
    return 0;
}

输出如下:

0    1    4    9    872356
0    1    4    3297856
0    1    4    3857296
0    1    4    5827396
0    1    4    6385729
0    1    4    8567329
0    1    4    9572836
0    1    9    25    36    784
0    1    36    529    784
0    1    49    872356
0    1    64    537289
0    1    256    73984
0    1    625    73984
0    4    16    537289
0    4    25    81    7396
0    4    25    139876
0    4    25    391876
0    4    289    15376
0    9    25    361    784
0    9    81    324    576
0    9    324    15876
0    9    13527684
0    9    34857216
0    9    65318724
0    9    73256481
0    9    81432576
0    16    25    73984
0    16    784    5329
0    25    784    1369
0    25    784    1936
0    25    841    7396
0    36    81    74529
0    36    81    79524
0    36    729    5184
0    36    5184729
0    36    5948721
0    81    324    7569
0    81    576    3249
0    81    729    4356
0    81    2537649
0    81    5673924
0    81    7436529
0    81    9253764
0    324    751689
0    361    529    784
0    576    321489
0    576    349281
0    576    381924
0    729    385641
0    3249    15876
0    4356    71289
0    8649    35721
0    139854276
0    152843769
0    157326849
0    215384976
0    245893761
0    254817369
0    326597184
0    361874529
0    375468129
0    382945761
0    385297641
0    412739856
0    523814769
0    529874361
0    537219684
0    549386721
0    587432169
0    589324176
0    597362481
0    615387249
0    627953481
0    653927184
0    672935481
0    697435281
0    714653289
0    735982641
0    743816529
0    842973156
0    847159236
0    923187456
1    4    9    36    87025
1    4    9    7203856
1    4    9    8673025
1    4    68973025
1    4    85063729
1    4    86397025
1    4    98327056
1    9    25    760384
1    9    784    30625
1    25    36    47089
1    25    3748096
1    25    6390784
1    36    49    87025
1    36    784    9025
1    49    7203856
1    49    8673025
1    289    357604
1    529    760384
1    784    390625
1    784    635209
4    9    361    87025
4    25    81    30976
4    25    3798601
4    289    173056
4    1369    87025
4    1936    87025
4    2809    15376
4    3025    17689
4    3025    18769
4    3025    78961
4    3025    81796
4    5329    67081
9    16    784    3025
9    36    7851204
9    81    324    7056
9    81    576    2304
9    81    4730625
9    81    6734025
9    324    576081
9    576    408321
9    576    423801
9    1764    38025
9    2304    15876
9    4761    38025
9    5184    20736
9    5184    30276
9    6084    35721
9    102576384
9    105637284
9    158306724
9    176305284
9    180472356
9    183467025
9    187635204
9    208571364
9    218034756
9    284057316
9    307265841
9    316057284
9    430728516
9    472801536
9    475283601
9    560837124
9    570684321
9    576432081
9    734681025
9    783104256
9    825470361
9    853107264
16    784    93025
25    361    47089
25    784    39601
25    841    30976
36    81    257049
36    81    497025
36    81    725904
36    19847025
36    57108249
36    71520849
36    80514729
36    94187025
49    361    87025
81    576    23409
81    576    39204
81    729    63504
81    2304    7569
81    3249    7056
81    32970564
81    34257609
81    45239076
81    56972304
81    70459236
81    73925604
81    74390625
169    784    3025
196    784    3025
324    576    1089
324    576    9801
324    6517809
324    8590761
361    784    9025
576    1034289
576    1432809
576    2039184
576    2893401
576    3814209
576    9108324
729    3048516
729    4835601
729    5308416
784    961    3025
1764    893025
2304    751689
3249    576081
4761    893025
5184    207936
5184    603729
7056    321489
7056    349281
7056    381924
7569    408321
7569    423801
8649    731025
15876    23409
15876    39204
20736    51984
20736    95481
30276    51984
30276    95481
38025    47961
63504    71289
1026753849
1042385796
1098524736
1237069584
1248703569
1278563049
1285437609
1382054976
1436789025
1503267984
1532487609
1547320896
1643897025
1827049536
1927385604
1937408256
2076351489
2081549376
2170348569
2386517904
2431870596
2435718609
2571098436
2913408576
3015986724
3074258916
3082914576
3089247561
3094251876
3195867024
3285697041
3412078569
3416987025
3428570916
3528716409
3719048256
3791480625
3827401956
3928657041
3964087521
3975428601
3985270641
4307821956
4308215769
4369871025
4392508176
4580176329
4728350169
4730825961
4832057169
5102673489
5273809641
5739426081
5783146209
5803697124
5982403716
6095237184
6154873209
6457890321
6471398025
6597013284
6714983025
7042398561
7165283904
7285134609
7351862049
7362154809
7408561329
7680594321
7854036129
7935068241
7946831025
7984316025
8014367529
8125940736
8127563409
8135679204
8326197504
8391476025
8503421796
8967143025
9054283716
9351276804
9560732841
9614783025
9761835204
9814072356
sum = 300

--------------------------------
Process exited after 3.196 seconds with return value 0
请按任意键继续. . .

 


棋子换位

有n个棋子A,n个棋子B,在棋盘上排成一行。
它们中间隔着一个空位,用“.”表示,比如:

AAA.BBB

现在需要所有的A棋子和B棋子交换位置。
移动棋子的规则是:
1. A棋子只能往右边移动,B棋子只能往左边移动。
2. 每个棋子可以移动到相邻的空位。
3. 每个棋子可以跳过相异的一个棋子落入空位(A跳过B或者B跳过A)。

AAA.BBB 可以走法:
移动A ==> AA.ABBB
移动B ==> AAAB.BB

跳走的例子:
AA.ABBB ==> AABA.BB

以下的程序完成了AB换位的功能,请仔细阅读分析源码,填写划线部分缺失的内容。

 

#include <stdio.h>
#include <string.h>

void move(char* data, int from, int to)
{
    data[to] = data[from];
    data[from] = '.';
}

int valid(char* data, int k)
{
    if(k<0 || k>=strlen(data)) return 0;
    return 1;
}
    
void f(char* data)
{
    int i;
    int tag;
    int dd = 0; // 移动方向
    
    while(1){
        tag = 0;
        for(i=0; i<strlen(data); i++){
            if(data[i]=='.') continue;
            if(data[i]=='A') dd = 1;
            if(data[i]=='B') dd = -1;
            
            if(valid(data, i+dd) && valid(data,i+dd+dd) 
            && data[i+dd]!=data[i] && data[i+dd+dd]=='.'){ 
            //如果能跳... 
                move(data, i, i+dd+dd);
                printf("%s\n", data);
                tag = 1;
                break;
            }
        }
        
        if(tag) continue;
        
        for(i=0; i<strlen(data); i++){
            if(data[i]=='.') continue;
            if(data[i]=='A') dd = 1;
            if(data[i]=='B') dd = -1;            
                 
            if(valid(data, i+dd) && data[i+dd]=='.'){ 
            // 如果能移动...
                if( ______________________ ) continue;  //填空位置 
                move(data, i, i+dd);
                printf("%s\n", data);
                tag = 1;
                break;
            }
        }
        
        if(tag==0) break;                    
    }
}
    
int main()
{
    char data[] = "AAA.BBB";    
    f(data);
    return 0;
}

 

注意:只提交划线部分缺少的代码,不要复制已有代码或填写任何多余内容。

 

#include <stdio.h>
#include <string.h>

void move(char* data, int from, int to)
{
    data[to] = data[from];
    data[from] = '.';
}

int valid(char* data, int k)
{
    if(k<0 || k>=strlen(data)) return 0;
    return 1;
}
    
void f(char* data)
{
    int i;
    int tag;
    int dd = 0; // 移动方向
    
    while(1){
        tag = 0;
        for(i=0; i<strlen(data); i++){
            if(data[i]=='.') continue;
            if(data[i]=='A') dd = 1;
            if(data[i]=='B') dd = -1;
            
            if(valid(data, i+dd) && valid(data,i+dd+dd) 
            && data[i+dd]!=data[i] && data[i+dd+dd]=='.'){ 
            //如果能跳... 
                move(data, i, i+dd+dd);
                printf("%s\n", data);
                tag = 1;
                break;
            }
        }
        
        if(tag) continue;
        
        for(i=0; i<strlen(data); i++){
            if(data[i]=='.') continue;
            if(data[i]=='A') dd = 1;
            if(data[i]=='B') dd = -1;            
                 
            if(valid(data, i+dd) && data[i+dd]=='.'){ 
            // 如果能移动...
            /*    if(
                ((valid(data,i-dd)&&data[i-dd]!=data[i])||!valid(data,i-dd)) 
                && ((valid(data,i+dd+dd) && data[i+dd+dd]==data[i])||!valid(data,i+dd+dd)) 
                && ((valid(data,i-dd-dd) && data[i-dd-dd]!=data[i])||!valid(data,i-dd-dd))
                && ((valid(data,i+dd+dd+dd) && data[i+dd+dd+dd]==data[i])||!valid(data,i+dd+dd+dd))
                 ) continue;  //填空位置,解决不正确停止的问题  
            */
                move(data, i, i+dd);
                printf("%s\n", data);
                tag = 1;
                break;
            }
        }
        
        if(tag==0) break;                    
    }
}
    
int main()
{
    char data[] = "AAA.BBB";    
    f(data);
    return 0;
}

 

#include <stdio.h>
#include <string.h>

void move(char* data, int from, int to)
{
    data[to] = data[from];
    data[from] = '.';
}

int valid(char* data, int k)
{
    if(k<0 || k>=strlen(data)) return 0;
    return 1;
}
    
void f(char* data)
{
    int i;
    int tag;
    int dd = 0; // 移动方向
    
    while(1){
        tag = 0;
        for(i=0; i<strlen(data); i++){
            if(data[i]=='.') continue;
            if(data[i]=='A') dd = 1;
            if(data[i]=='B') dd = -1;
            
            if(valid(data, i+dd) && valid(data,i+dd+dd) 
            && data[i+dd]!=data[i] && data[i+dd+dd]=='.'){ 
            //如果能跳... 
                move(data, i, i+dd+dd);
                printf("%s\n", data);
                tag = 1;
                break;
            }
        }
        
        if(tag) continue;
        
        for(i=0; i<strlen(data); i++){
            if(data[i]=='.') continue;
            if(data[i]=='A') dd = 1;
            if(data[i]=='B') dd = -1;            
                 
            if(valid(data, i+dd) && data[i+dd]=='.'){ 
                // 如果能移动...
                //如果data[i]元素前进方向的反方向的元素存在并且和data[i]不同
                //并且data[i]元素请进方向的前方第二个位置元素存在并且和data[i]相同,那么停止这一次移动。
                //没有可以跳的  该棋子可移动之前 判断它旁边字母是否与他相同 若相同则移动 
                //若不同 则说明这是刚刚跳过来的 在判断“ . ”后面可还有字母 若有判断与该棋子旁边的旗子是否相同 若相同则说明不该这一旗子移动 continue 过去 
                if(valid(data, i-dd) && data[i-dd]!=data[i]&& valid(data, i+dd+dd) && data[i+dd+dd]==data[i-dd]) continue;  //填空位置 
                move(data, i, i+dd);
                printf("%s\n", data);
                tag = 1;
                break;
            }
        }
        
        if(tag==0) break;                    
    }
}
    
int main()
{
    char data[] = "AAAAA.BBBBB";    
    f(data);
    return 0;
}

 

机器人塔

 

X星球的机器人表演拉拉队有两种服装,A和B。

他们这次表演的是搭机器人塔。

 

类似:

 

     A

    B B

   A B A

  A A B B

 B B B A B

A B A B B A

 

队内的组塔规则是:

  

  A 只能站在 AA 或 BB 的肩上。

  B 只能站在 AB 或 BA 的肩上。

 

你的任务是帮助拉拉队计算一下,在给定A与B的人数时,可以组成多少种花样的塔。

 

输入一行两个整数 M 和 N,空格分开(0<M,N<500),分别表示A、B的人数,保证人数合理性。

 

要求输出一个整数,表示可以产生的花样种数。

 

例如:

用户输入:

1 2

 

程序应该输出:

3

 

 

再例如:

用户输入:

3 3

 

程序应该输出:

4

 

资源约定:

峰值内存消耗 < 256M                     

CPU消耗  < 1000ms

 

请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

 

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

 

注意: main函数需要返回0

注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。

注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

 

提交时,注意选择所期望的编译器类型。

//题目没有看清楚,思路错误的想到二叉树上面,所以下面是完全错误的答案
#include<algorithm> #include<iostream> #include<cstdio> #include<cmath> using namespace std; typedef long long LL; LL a[33][501][501],b[33][501][501]; int main(void) { a[1][1][0]=1,a[2][3][0]=1,a[2][1][2]=1; b[1][0][1]=1,b[2][1][2]=2; int M,N; cin >> M >> N; int x = (-1+(int)(sqrt(1.0+8*M+8*N)+0.5))/2; //cout <<"x="<<x<<endl; for(int k=3;k<=x;k++) for(int i=0;i<=k*(k+1)/2;i++) { int j=k*(k+1)/2-i; //计算 a[k][i][j] , b[k][i][j] if(i>=1) { //a[k][i][j] for(int m=1;m+1<=i-1;m++) a[k][i][j]+=a[k-1][m][k*(k-1)/2-m]*a[k-1][i-1-m][k*(k-1)/2-(i-1-m)]; for(int n=1;n+1<=j;n++) a[k][i][j]+=b[k-1][k*(k-1)/2-n][n]*b[k-1][k*(k-1)/2-(j-n)][j-n]; } if(j>=2) { for(int n=1;n<=j-1;n++) { b[k][i][j]+=2*a[k-1][k*(k-1)/2-(j-1-n)][j-1-n]*b[k-1][k*(k-1)/2-n][n]; /* if(i==3 && j==3) { printf("b[3][3][3] += 2* a[%d][%d][%d] * b[%d][%d][%d] = 2* %d * %d\n",k-1,k*(k-1)/2-(j-1-n),j-1-n,k-1,k*(k-1)/2-n,n,a[k-1][k*(k-1)/2-(j-1-n)][j-1-n],b[k-1][k*(k-1)/2-n][n]); } */ } } } //for(int i=0;i<=6;i++) printf("a[3][%d][%d]=%d\n",i,6-i,a[3][i][6-i]); //for(int i=0;i<=6;i++) printf("b[3][%d][%d]=%d\n",i,6-i,b[3][i][6-i]); LL sum = a[x][M][N]+b[x][M][N]; cout << sum ; return 0; }

 再给出一个暴力求解的方法:只能通过估计20%左右的数据估计。

位向量法:解答树的节点虽然多,但是速度挺快的,但是要求n是一个非常小的整数,但是这里的显然不可满足条件。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

int a[50],M,N,sum,x;

void dfs(int cur)
{
    if(cur==x)
    {
        int z=x,numa=0,numb=0;
        while(z)
        {
            for(int i=0;i<z;i++)
                if(a[i]) numa++;
                else numb++;
            z--;
            for(int i=0;i<z;i++)
                if(a[i]==a[i+1]) a[i]=1;
                else a[i]=0;
        }
        if(numa==M && numb==N) sum++;
    }
    else 
    {
        a[cur]=1;
        dfs(cur+1);
        a[cur]=0;
        dfs(cur+1); 
    }
}

int main(void)
{
    cin >> M >> N;
    int i=1;
    while(i*(i+1)/2 != M+N) i++;
    x = i;
    dfs(0);
    cout << sum << endl;
    return 0;
}

下面是一个示例:

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;

void print_subset(int n,int *b,int cur)
{
    if(cur==n)
    {
        for(int i=0;i<cur;i++)
            printf("%d",b[i]);
        printf("\n");
        return ; 
    }
    b[cur]=1;
    print_subset(n,b,cur+1);
    b[cur]=0;
    print_subset(n,b,cur+1);
}

int main(void)
{
    int n;
    cin >> n;
    int b[100];
    print_subset(n,b,0);
    return 0;    
} 
/*
输入5,结果如下: 
5
11111
11110
11101
11100
11011
11010
11001
11000
10111
10110
10101
10100
10011
10010
10001
10000
01111
01110
01101
01100
01011
01010
01001
01000
00111
00110
00101
00100
00011
00010
00001
00000
*/

然后再给出一个自己写的暴力破解的代码,这个代码是错误的,输出序列,发现序列是不正确的:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath> 
using namespace std;
int M,N,x,sum;
int a[50];
void DFS(int cur,int numa,int numb)
{
    if(cur==x)
    {
        //输出序列 
        for(int i=0;i<x;i++) printf("%d",a[i]);
        cout << endl;
        /*
        for(int i=x-1;i>=1;i--)
        {
            for(int j=0;j<i;j++)
            {
                if(a[j]==a[j+1])
                {
                    a[j]=1;
                    numa++;
                }
                else 
                {
                    a[j]=0;
                    numb++;
                }
            }
        }
        */ 
        int z=x;
            numa=numb=0;
            for(int i=0;i<z;i++) if(a[i]) numa++; else numb++;
            //此时结果是正确的,说明递归的过程中,numa和numb计算出错了。 
        
        while(z)
        {
            for(int i=0;i+1<z;i++)
                if(a[i]==a[i+1]) a[i]=1,numa++;
                else a[i]=0,numb++;
            z--;    
        } 
        if(numa==M && numb==N) sum++;
    }
    else 
    {
        a[cur]=1;
        DFS(cur+1,numa+1,numb);
        a[cur]=0;
        DFS(cur+1,numa,numb+1);
    }
}
int main(void)
{
    
    cin >> M >> N;
    x = (-1+(int)(sqrt(1.0+8*M+8*N)+0.5))/2; 
    
    DFS(0,0,0);
    cout << sum << endl;
    return 0;
} 
/*
3 3
111
110
001
000
011
010
101
100
4
*/ 

找了半天都没有找出来哪里出了问题,后来发现再最后修改a数组的时候,修改了不能修改的数据,这时候正常的做法是使用一个新的数组记录a的值,然后再计算。

这个时候估计也可以想到,第一个方法也是有问题的,但是恰好数据通过,没有注意到这个问题。然后再重新写一个代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

int b[100],M,N,sum,x;

void dfs(int cur)
{
    if(cur==x)
    {
        int a[100];
        for(int i=0;i<x;i++) cout << b[i];
        cout << endl;
        int z=x,numa=0,numb=0;
        for(int i=0;i<x;i++) a[i]=b[i]; 
        while(z)
        {
            for(int i=0;i<z;i++)
                if(a[i]) numa++;
                else numb++;
            z--;
            for(int i=0;i<z;i++)
                if(a[i]==a[i+1]) a[i]=1;
                else a[i]=0;
        }
        if(numa==M && numb==N) sum++;
    }
    else 
    {
        b[cur]=1;
        dfs(cur+1);
        b[cur]=0;
        dfs(cur+1); 
    }
}

int main(void)
{
    cin >> M >> N;
    int i=1;
    while(i*(i+1)/2 != M+N) i++;
    x = i;
    dfs(0);
    cout << sum << endl;
    return 0;
}

这样就是一个可以正常运行计算出部分答案的程序了。

posted @ 2018-05-10 21:29  最美遇见你  阅读(386)  评论(0编辑  收藏  举报