蓝桥杯2011c/c++组高职决赛题分析

题一:

/*
    从4个人中选2个人参加活动,一共有6种选法。

    从n个人中选m个人参加活动,一共有多少种选法?下面的函数实现了这个功能。

    请仔细分析代码,填写缺少的部分(下划线部分)。

    注意:请把填空的答案(仅填空处的答案,不包括题面)存入考生文件夹下对应题号的“解答.txt”中即可。
    直接写在题面中不能得分。

    // n 个元素中任取 m 个元素,有多少种取法
    int f(int n, int m)
    {
    if(m>n) return 0;
    if(m==0) _______________;

    return f(n-1,m-1) + _____________;
    }
 */
#include <iostream>

using namespace std;

// n 个元素中任取 m 个元素,有多少种取法
int f(int n, int m)
{
    if(m>n) return 0;
    if(m==0) return 1;

    return f(n-1,m-1) + f(n - 1,m);
}

int main()
{
    cout << f(5,3) << endl;
    return 0;
}

题二:

/**
如果一个自然数的平方数的尾部仍然为该自然数本身,则称其为自守数。
例如:
5 x 5 = 25
76 x 76 = 5776
625 x 625 = 390625

下面代码的目的是寻找出2千万以内的所有自守数。

注意,2千万的平方已经超出了整数表达的最大范围,所以该程序使用了一个巧妙的方案。
如果我们仔细观察乘法的计算过程,就会发现实际上对乘积的尾数有贡献的环节,从而不用真正计算出整个乘积。

请分析代码并填写缺失的部分。

注意:请把填空的答案(仅填空处的答案,不包括题面)存入考生文件夹下对应题号的“解答.txt”中即可。
直接写在题面中不能得分。


 */
#include <iostream>

using namespace std;


void zishou()
{
    int n;
    for(n=1; n<20 * 1000 * 1000; n++)
    {
        int n2 = n;  
        int m = 0;
        for(;;)
        {
            if(n2==0) 
            {
                printf("%d\n", n);
                break;
            }

            int k = n2 % 10;  // 从末尾开始,取出乘数的每位数字
            m += k * n;  // 累计乘积
            if(m % 10 != n2 % 10) break;
            m = m / 10;  // 舍去累计乘积的末位
            n2 = n2 / 10;  
        }
    }
}
int main()
{
    zishou();
    return 0;
}

题三:

写的有点夸张,有必要写个递归式

/**
看下面的算式:

□□ x □□ = □□ x □□□

它表示:两个两位数相乘等于一个两位数乘以一个三位数。

如果没有限定条件,这样的例子很多。

但目前的限定是:这9个方块,表示1~9的9个数字,不包含0。
该算式中1至9的每个数字出现且只出现一次!

比如:
46 x 79 = 23 x 158
54 x 69 = 27 x 138
54 x 93 = 27 x 186
.....

请编程,输出所有可能的情况!

注意:左边的两个乘数交换算同一方案,不要重复输出!


要求考生把所有函数写在一个文件中。调试好后,存入与考生文件夹下对应题号的“解答.txt”中即可。
相关的工程文件不要拷入。 
对于编程题目,要求选手给出的解答完全符合ANSI C标准,不能使用c++特性;
不能使用诸如绘图、中断调用等硬件相关或操作系统相关的API。
 */
/**
            c       a               i         g         e
            d       b                         h         f
        -------------            ------------------------
           cb       ab              if        gf        ef
    cd     ad                 ih    gh        eh
---------------------        ----------------------------
    cd    cb+ad     ab   和    ih   if+gh     gf+eh     ef
    C1    B1        A1   进位  D2   C2        B2        A2
D   C     B         A    余数  D    C         B         A
 */
#include <iostream>

using namespace std;

int main()
{
    int num[10] = {0};
    memset(num,0,sizeof(num));

    for (int a = 1;a < 10;a++)
    {
        num[a] = 1;
        for (int b = 1;b < 10;b++)
        {
            if (num[b] == 1)
            {
                continue;
            }
            num[b] = 1;
            for (int e = 1;e < 10;e++)
            {
                if (num[e] == 1)
                {
                    continue;
                }
                num[e] = 1;
                for (int f = 1;f < 10;f++)
                {
                    if (num[f] == 1)
                    {
                        continue;
                    }
                    num[f] = 1;
                    int A1 = a * b;
                    int A2 = e * f;


                    if (A1 % 10 != A2 % 10)
                    {
                        num[f] = 0;
                        continue;
                    }
                    A1 /= 10;
                    A2 /= 10;

                    for (int c = 1;c < 10;c++)
                    {
                        if (num[c] == 1)
                        {
                            continue;
                        }
                        num[c] = 1;
                        for (int d = 1;d < 10;d++)
                        {
                            if (num[d] == 1 || d < c)
                            {
                                continue;
                            }
                            num[d] = 1;
                            for (int g = 1;g < 10;g++)
                            {
                                if (num[g] == 1)
                                {
                                    continue;
                                }
                                num[g] = 1;
                                for (int h = 1;h < 10;h++)
                                {
                                    if (num[h] == 1)
                                    {
                                        continue;
                                    }
                                    num[h] = 1;

                                    int B1 = b * c + a * d + A1;
                                    int B2 = g * f + e * h + A2;

                                    if (B1 % 10 != B2 % 10)
                                    {
                                        num[h] = 0;
                                        continue;
                                    }
                                    B1 /= 10;
                                    B2 /= 10;
                                    for (int i = 1;i < 10;i++)
                                    {
                                        if (num[i] == 1)
                                        {
                                            continue;
                                        }
                                        num[i] = 1;

                                        int C1 = c * d + B1;
                                        int C2 = i * f + h * g + B2;

                                        if (C1 % 10 != C2 % 10)
                                        {
                                            num[i] = 0;
                                            continue;
                                        }
                                        C1 /= 10;
                                        C2 /= 10;
                                        if (C1 != i * h + C2)
                                        {
                                            num[i] = 0;
                                            continue;
                                        }
                                        cout << c << a << " x " << d << b << " = " << h << f << " x " << i << g << e << endl;
                                        num[i] = 0;
                                    }
                                    num[h] = 0;
                                }
                                num[g] = 0;
                            }
                            num[d] = 0;
                        }
                        num[c] = 0;
                    }
                    num[f] = 0;
                }
                num[e] = 0;
            }
            num[b] = 0;
        }
        num[a] = 0;
    }
    return 0;
}

题三递归版本:

#include <iostream>

using namespace std;

void dfs(int a[],int b_used[],int lev)
{
    if (lev == 9)
    {
        int A1 = a[0] * a[1] / 10;
        int A2 = a[2] * a[3] / 10;

        int B1 = (a[4] * a[1] + a[0] * a[5] + A1) / 10;
        int B2 = (a[6] * a[3] + a[2] * a[7] + A2) / 10;

        int C_1 = a[4] * a[5] + B1;
        int C_2 = a[8] * a[3] + a[6] * a[7] + B2;

        if (C_1 % 10 != C_2 % 10)
        {
            return;
        }
        int C1 = C_1 / 10;
        int C2 = C_2 / 10;
        if (C1 != a[8] * a[7] + C2)
        {
            return;
        }
        cout << a[4] << a[0]
            << " x "
            << a[5] << a[1]
            << " = "
            << a[7] << a[3]
            << " x "
            << a[8] << a[6] << a[2]
            << endl;
        return;
    }
    if (lev == 4)
    {
        int ab = a[0] * a[1];
        int ef = a[2] * a[3];

        if (ab % 10 != ef % 10)
        {
            return;
        }
    }
    if (lev == 6)
    {
        if (a[5] < a[4])
        {
            return;
        }
    }
    if (lev == 8)
    {
        int A1 = a[0] * a[1] / 10;
        int A2 = a[2] * a[3] / 10;

        int B_1 = a[4] * a[1] + a[0] * a[5] + A1;
        int B_2 = a[6] * a[3] + a[2] * a[7] + A2;

        if (B_1 % 10 != B_2 % 10)
        {
            return;
        }
    }
    for (int i = 1;i < 10;i++)
    {
        if (b_used[i] == 1)
        {
            continue;
        }
        b_used[i] = 1;
        a[lev] = i;
        dfs(a,b_used,lev + 1);
        b_used[i] = 0;
    }
    return;
}

int main()
{
    int a[9] = {0};
    int b_used[10] = {0};

    dfs(a,b_used,0);

    return 0;
}


题四:

/**
魔方可以对它的6个面自由旋转。

我们来操作一个2阶魔方(如图1所示):
为了描述方便,我们为它建立了坐标系。

各个面的初始状态如下:
x轴正向:绿
x轴反向:蓝
y轴正向:红
y轴反向:橙
z轴正向:白
z轴反向:黄

假设我们规定,只能对该魔方进行3种操作。分别标记为:
x 表示在x轴正向做顺时针旋转
y 表示在y轴正向做顺时针旋转
z 表示在z轴正向做顺时针旋转

xyz 则表示顺序执行x,y,z 3个操作

题目的要求是:
用户从键盘输入一个串,表示操作序列。
程序输出:距离我们最近的那个小方块的3个面的颜色。
顺序是:x面,y面,z面。

例如:在初始状态,应该输出:
绿红白

初始状态下,如果用户输入:
x
则应该输出:
绿白橙

初始状态下,如果用户输入:
zyx
则应该输出:
红白绿


请编程实现所述功能。


要求考生把所有函数写在一个文件中。调试好后,存入与考生文件夹下对应题号的“解答.txt”中即可。
相关的工程文件不要拷入。 
对于编程题目,要求选手给出的解答完全符合ANSI C标准,不能使用c++特性;
不能使用诸如绘图、中断调用等硬件相关或操作系统相关的API。

 */
#include <iostream>
#include <string>

using namespace std;

static int A[4];
static int B[4];
static int C[4];
static int D[4];
static int E[4];
static int F[4];

#define GREEN   1
#define WHITE   2
#define ORANGE  3
#define RED     4
#define YELLOW  5
#define BLUE    6

string get_color(int id)
{
    switch (id)
    {
    case GREEN:
        return "绿";
    case WHITE:
        return "白";
    case ORANGE:
        return "橙";
    case RED:
        return "红";
    case YELLOW:
        return "黄";
    case BLUE:
        return "蓝";
    }
}
void init()
{
    for (int i = 0;i < 4;i++)
    {
        A[i] = GREEN;
        B[i] = WHITE;
        C[i] = ORANGE;
        D[i] = RED;
        E[i] = YELLOW;
        F[i] = BLUE;
    }
}
void x_rotate()
{
    int t1 = A[0];
    int t2 = 0;
    A[0] = A[2];
    A[2] = A[3];
    A[3] = A[1];
    A[1] = t1;

    t1 = E[0];
    t2 = E[1];

    E[0] = D[3];
    E[1] = D[2];

    D[2] = B[2];
    D[3] = B[3];

    B[2] = C[2];
    B[3] = C[3];

    C[2] = t2;
    C[3] = t1;
    return;
}
void y_rotate()
{
    int t1 = D[0];
    int t2 = 0;

    D[0] = D[2];
    D[2] = D[3];
    D[3] = D[1];
    D[1] = t1;

    t1 = F[1];
    t2 = F[3];

    F[1] = B[1];
    F[3] = B[3];

    B[1] = A[1];
    B[3] = A[3];

    A[1] = E[1];
    A[3] = E[3];

    E[1] = t1;
    E[3] = t2;
    return;
}
void z_rotate()
{
    int t1 = B[0];
    int t2 = 0;

    B[0] = B[2];
    B[2] = B[3];
    B[3] = B[1];
    B[1] = t1;

    t1 = F[2];
    t2 = F[3];

    F[2] = C[3];
    F[3] = C[1];

    C[1] = A[0];
    C[3] = A[1];

    A[0] = D[2];
    A[1] = D[0];

    D[2] = t2;
    D[0] = t1;
    return;
}
int main()
{
    string str;
    while (cin >> str)
    {
        init();
        for (int i = 0;i < str.size();i++)
        {
            switch (str[i])
            {
            case 'x':
                x_rotate();
                break;
            case 'y':
                y_rotate();
                break;
            case 'z':
                z_rotate();
                break;
            }
        }
        cout << get_color(A[1]) << get_color(D[2]) << get_color(B[3]) << endl;
    }
    return 0;
}
题五:

/**
已知平面上若干个点的坐标。

需要求出在所有的组合中,4个点间平均距离的最小值(四舍五入,保留2位小数)。

比如有4个点:a,b,c,d, 则平均距离是指:ab, ac, ad, bc, bd, cd 这6个距离的平均值。

每个点的坐标表示为:横坐标,纵坐标

坐标的取值范围是:1~1000

所有点的坐标记录在in.txt中,请读入该文件,然后计算。

注意:我们测试您的程序的时候,in.txt 可能会很大,比如包含上万条记录。

举例:
如果,in.txt 内的值为:

10,10
20,20
80,50
10,20
20,10

则程序应该输出:
11.38


请编程,读入in.txt文件,计算并输出4个点平均距离的最小值。


要求考生把所有函数写在一个文件中。调试好后,存入与考生文件夹下对应题号的“解答.txt”中即可。
相关的工程文件不要拷入。 
对于编程题目,要求选手给出的解答完全符合ANSI C标准,不能使用c++特性;
不能使用诸如绘图、中断调用等硬件相关或操作系统相关的API。

 */
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <iomanip>
#include <algorithm>

using namespace std;

struct Point
{
    int x,y;
    int x2y2;
    Point()
    {
        return;
    }
    Point(int t_x,int t_y)
        :x(t_x),
        y(t_y)
    {
        x2y2 = t_x * t_x + t_y * t_y;
    }
    const Point& operator=(const Point& point)
    {
        x = point.x;
        y = point.y;
        x2y2 = point.x2y2;

        return *this;
    }
};

bool operator<(const Point& left,const Point& right)
{
    if (left.x2y2 < right.x2y2)
    {
        return true;
    }
    return false;
}
bool operator==(const Point& left,const Point& right)
{
    if (left.x2y2 == right.x2y2)
    {
        return true;
    }
    return false;
}
typedef vector<Point> PointArray;

static double min_sum = 0x3f3f3f3f;
static int ps[4];

inline int get_dis_no_sqrt(PointArray& points,int x,int y)
{
    int off_x = 0;
    int off_y = 0;

    off_x = points[x].x - points[y].x;
    off_y = points[x].y - points[y].y;

    off_x = off_x * off_x;
    off_y = off_y * off_y;
    return off_x + off_y;
}
inline void my_sort(PointArray& points)
{
    int s = points.size();

    for (int i = 0;i < s;i++)
    {
        int min_x_y = 0x3f3f3f3f;
        
        /*对所有的进行重排*/
        for (int j = i + 1;j < s;j++)
        {
            if (points[j].x - points[i].x > min_x_y || points[j].y - points[i].y > min_x_y)
            {
                break;
            }
            int dis_i_i_1 = get_dis_no_sqrt(points,i,i + 1);
            int dis_i_j = get_dis_no_sqrt(points,i,j);

            if (dis_i_i_1 < dis_i_j)
            {
                continue;
            }
            /*向后移动*/
            Point p = points[j];
            for (int k = j;k > i + 1;k--)
            {
                points[k] = points[k - 1];
            }
            points[i + 1] = p;
            min_x_y = (int)sqrt(dis_i_j * 1.0) + 1;

        }
    }
    return;
}

inline double get_dis(PointArray& points,int x,int y)
{
    return sqrt(double(get_dis_no_sqrt(points,x,y)));
}
void search(PointArray& points,int p4[],int off,int lev)
{
    if (lev == 4)
    {
        double sum = 0;

        for (int i = 0;i < 3;i++)
        {
            sum += get_dis(points,p4[i],p4[i + 1]);
        }
        sum += get_dis(points,p4[0],p4[2]);
        sum += get_dis(points,p4[0],p4[3]);
        sum += get_dis(points,p4[1],p4[3]);
        if (min_sum > sum)
        {
            min_sum = sum;
            for (int i = 0;i < 4;i++)
            {
                ps[i] = p4[i];
            }
        }
        return;
    }
    for (int i = off;i < points.size();i++)
    {
        if (get_dis(points,i,p4[0]) > min_sum)
        {
            break;
        }
        p4[lev] = i;
        search(points,p4,i + 1,lev + 1);
    }
    return;
}
int main()
{
    fstream fst("in.txt",ios::in);
    int x,y;
    char ch;

    PointArray points;

    while (fst >> x >> ch >> y)
    {
        Point p(x,y);
        points.push_back(p);
    }

    sort(points.begin(),points.end());
    my_sort(points);
    int s = points.size();
    if (s < 4)
    {
        cout << "0.00" << endl;
    }
    else
    {
        int p4[4] = {0};

        for (int i = 0;i < s - 4;i++)
        {
            memset(p4,0,sizeof(p4));
            p4[0] = i;
            search(points,p4,i,0);
        }

        cout << fixed << setprecision(2) << min_sum / 6 << endl;
        cout << endl;
    }
    return 0;
}





  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值