zoukankan      html  css  js  c++  java
  • 蓝桥杯测试


    一步之遥

    从昏迷中醒来,小明发现自己被关在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
    ",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("
    ");
            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("
    ");
        }
        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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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 ",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 ",i,6-i,a[3][i][6-i]); //for(int i=0;i<=6;i++) printf("b[3][%d][%d]=%d ",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("
    ");
            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;
    }

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

  • 相关阅读:
    Redhat6 —— Yum详解
    jQuery——bind绑定多事件用法
    织梦之路——织梦自由列表页分页链接绝对路径化(SEO)
    PHP算法——等宽等像素值截取字符串
    PHP算法——文件大小排序(KB、MB、GB、TB)
    HDU 3647 Tetris
    HDU 2442 Bricks
    ZOJ 2112 Dynamic Rankings
    HDU 3001 Travelling
    HDU 3559 Frost Chain
  • 原文地址:https://www.cnblogs.com/zuimeiyujianni/p/9021443.html
Copyright © 2011-2022 走看看