回 帖 发 新 帖 刷新版面

主题:入门必做的题

1.  给定等式  A B C D E     其中每个字母代表一个数字,且不同数字对应不
                    D F G     同字母。编程求出这些数字并且打出这个数字的
             +      D F G     算术计算竖式。

             ───────

                X Y Z D E



  2. A、B、C、D、E五名学生有可能参加计算机竞赛,根据下列条件判断哪些
  人参加了竞赛:

   (1)A参加时,B也参加;

   (2)B和C只有一个人参加;

   (3)C和D或者都参加,或者都不参加;

   (4)D和E中至少有一个人参加;

   (5)如果E参加,那么A和D也都参加。



  3. 打印一个 N*N 的方阵,N为每边           N=15  打印出下面图形
 字符的个数(3<N<20), 要求最               TTTTTTTTTTTTTTT
 外一层为"T", 第二层为"J", 从第三层               TJJJJJJJJJJJJJT
 起每层依次打印数字 1,2,3,...                     TJ11111111111JT
 (右图以N为15为例)                           TJ12222222221JT
                                                  TJ12333333321JT
                                                  TJ12344444321JT
                                                  TJ12345554321JT
                                                  TJ12345654321JT
                                                  TJ12345554321JT
                                                  TJ12344444321JT
                                                  TJ12333333321JT
                                                  TJ12222222221JT
                                                  TJ11111111111JT
                                                  TJJJJJJJJJJJJJT
                                                  TTTTTTTTTTTTTTT



  4. 在N行N列的数阵中, 数K(1〈=K〈=N)在每行和每列中出现且仅
  出现一次,这样的数阵叫N阶拉丁方阵。例如下图就是一个五阶拉丁方阵。
  编一程序,从键盘输入N值后,打印出所有不同的N阶拉丁方阵,并统计个数。

        1  2  3  4  5
        2  3  4  5  1
        3  4  5  1  2
        4  5  1  2  3
        5  1  2  3  4


  5. 输入一个十进数,将其转换成 N 进制数(0<N<=16)。

回复列表 (共635个回复)

71 楼

10.  如图1所示,编写程序计算               ┎┰┰┰┰┰┰┰┰┰┒
    大大小小正方形共有多少?当最小          ┠╂╂╂╂╂╂╂╂╂┨
    正方行边长为1时,它们的总面积          ┠╂╂╂╂╂╂╂╂╂┨
    共为多少?                              ┠╂╂╂╂╂╂╂╂╂┨
                                            ┠╂╂╂╂╂╂╂╂╂┨
                                            ┠╂╂╂╂╂╂╂╂╂┨
                                            ┠╂╂╂╂╂╂╂╂╂┨
                                            ┠╂╂╂╂╂╂╂╂╂┨
                                            ┠╂╂╂╂╂╂╂╂╂┨
                                            ┠╂╂╂╂╂╂╂╂╂┨
                                            ┖┸┸┸┸┸┸┸┸┸┚

10.解答
#include<stdio.h>
#define N 10
int main(void)
{
    long count=0, s=0;
    int a;
    for(a=1; a<=N; ++a)
    {
        int n = N-a+1;
        n *= n;    // 边长为a的正方形共有(N-a+1)*(N-a+1)个
        count += n;
        s += n*a*a;
    }
    printf("count = %ld, s = %ld\n", count, s);
}
运行结果:
count = 385, s = 5368

72 楼

11. 巧排数字。将1、2、...、20这20个数排成一排,使得相邻的两个数之
  和为一个素数,且首尾两数字之和也为一个素数。编程打印出所有的排法。

11.解答:
递归的进行全排列(当然,如果未排列完就发现不符合要求,则直接去除)
判断素数采用二分查找

#include<stdio.h>
// 40以内的素数表
int PrimeTable[] = {2,3,5,7,11,13,17,19,23,29,31,37};
// 函数IsPrime,判断一个数是否为素数,若是,返回1,否则返回0
// 实现:采用二分查找法,在PrimeTable数组中进行查找
int IsPrime(int n)
{
    int low = 0;
    int high = 12;    // 40以内的素数共12个
    while( low <= high )
    {
        int mid = (low+high)/2;
        if( PrimeTable[mid] == n )
            return 1;
        else if( PrimeTable[mid] > n )
            high = mid-1;
        else
            low = mid+1;
    }
    return 0;
}

int a[20];
int used[20] = {0};

void Solve(int start)
{
    int i;
    if( start == 20 )
    {
        if( !IsPrime(a[0]+a[19]) )
            return;
        for(i=0; i<20; ++i)
            printf("%4d",a[i]);
        return;
    }
    for(i=0; i<20; ++i)
    {
        if( used[i] )
            continue;
        if( start!=0 && !IsPrime(a[start-1]+i+1) )
            continue;
        used[i] = 1;
        a[start] = i+1;
        Solve(start+1);
        used[i] = 0;
    }
}

int main(void)
{
    Solve(0);
}

73 楼

12. 下图是一个集装箱仓库,阴影部分表示有集装箱存放不能通过,无阴影处为临时通
 道。当有人要从入口处到达出口处时,必须寻找可通过路线,请你找出可完成这个过程
 的最方便(即用最短路线)到达出口处的路径。

          ┎┰┰┰入口┰┰┰┰┰┰┰┰┰┰┰┰┰┰┰┰┰┰┰┰┰┰┰┰┒
          ┠╂╂╂──╂╂╂╂┸┸╂┸┸╂┸┸╂┸┸╂╂╂╂┸┸╂╂╂┨
          ┠╂╂╂──╂┸┸╂──╂┰┰╂┰┰╂──╂╂╂╂──╂╂╂┨
          ┠╂╂╂──╂┰┰╂┰┰╂╂╂╂╂╂╂──╂┸┸╂──╂╂╂┨
          ┠╂╂╂──╂╂╂╂╂╂╂╂╂╂╂╂╂┰┰╂┰┰╂┰┰╂╂╂┨
          ┠╂╂╂──╂┸┸╂┸┸╂┸┸╂┸┸╂┸┸╂┸┸╂┸┸╂╂╂┨
          ┠╂╂╂──╂┰┰╂┰┰╂┰┰╂──╂┰┰╂──╂┰┰╂╂╂┨
          ┠╂╂╂──╂╂╂╂╂╂╂╂╂╂──╂╂╂╂──╂╂╂╂╂╂┨
          ┠╂╂╂──╂╂╂╂┸┸╂┸┸╂──╂╂╂╂──╂┸┸╂╂╂┨
          ┠╂╂╂──╂╂╂╂┰┰╂┰┰╂┰┰╂╂╂╂┰┰╂──╂╂╂┨
          ┖┸┸┸──┸┸┸┸┸┸┸┸┸┸┸┸┸┸┸┸┸┸┸出口┸┸┸┚

12.解答:
#include<stdio.h>
#include<stdlib.h>

// 地图,在原地图周围加了一圈边界
// *表示边界,#表示不通,空格表示通道
char map[12][12] =
{
    '*','*','*','*','*','*','*','*','*','*','*','*',
    '*','#',' ','#','#','#','#','#','#','#','#','*',
    '*','#',' ','#',' ',' ',' ',' ','#',' ','#','*',
    '*','#',' ',' ',' ','#','#',' ','#',' ','#','*',
    '*','#',' ','#','#','#','#',' ',' ',' ','#','*',
    '*','#',' ','#','#','#','#','#','#','#','#','*',
    '*','#',' ',' ',' ',' ',' ',' ',' ',' ','#','*',
    '*','#',' ','#','#','#',' ','#',' ','#','#','*',
    '*','#',' ','#','#','#',' ','#',' ','#','#','*',
    '*','#',' ','#',' ',' ',' ','#',' ',' ','#','*',
    '*','#',' ','#','#','#','#','#','#',' ','#','*',
    '*','*','*','*','*','*','*','*','*','*','*','*',
};

int steps[12][12] = {0};

#define QueueSize 100
int RowQueue[QueueSize];
int ColQueue[QueueSize];
int Q_Head = 0, Q_Rear = 0;

#define EnQueue(i,j) do{RowQueue[Q_Rear]=(i);ColQueue[Q_Rear]=(j);++Q_Rear;}while(0)
#define DeQueue(i,j) do{(i)=RowQueue[Q_Head];(j)=ColQueue[Q_Head];++Q_Head;}while(0)
#define QueueNotEmpty (Q_Head != Q_Rear)

void Step(int i, int j, int lastnstep)
{
    if( map[i][j] != ' ' )
        return;
    if( steps[i][j] == 0 )
    {
        steps[i][j] = lastnstep + 1;
        EnQueue(i,j);
    }
    else if( steps[i][j] > lastnstep + 1 )
    {
        steps[i][j] = lastnstep + 1;
        EnQueue(i,j);
    }
}

void Solve(int InRow, int InCol, int OutRow, int OutCol)
{
    int i,j;
    int lastnstep;

    // 通过广度优先搜索求结果
    steps[InRow][InCol] = 1;
    EnQueue(InRow, InCol);
    while( QueueNotEmpty && steps[OutRow][OutCol]==0 )
    {
        DeQueue(i,j);
        lastnstep = steps[i][j];
        Step(i+1,j,lastnstep);
        Step(i,j+1,lastnstep);
        Step(i-1,j,lastnstep);
        Step(i,j-1,lastnstep);
    }
    if( steps[OutRow][OutCol] == 0 )
    {
        printf("No Answer!\n");
        return;
    }

    // 输出中间结果
    for(i=0;i<12;++i)
    {
        for(j=0;j<12;++j)
        {
            if( map[i][j] != ' ' )
                printf("%4c",map[i][j]);
            else
                printf("%4d",steps[i][j]);
        }
        printf("\n");
    }

    // 形成最终结果,地图上需要经过的路线用'o'标出
    i = OutRow;
    j = OutCol;
    map[InRow][InCol] = 'o';
    while( i!=InRow || j!=InCol )
    {
        int n = steps[i][j] - 1;
        map[i][j] = 'o';
        if( steps[i+1][j] == n )
            ++i;
        else if( steps[i-1][j] == n )
            --i;
        else if( steps[i][j+1] == n )
            ++j;
        else if( steps[i][j-1] == n )
            --j;
        else
        {
            printf("Error!");
            exit(1);
        }
    }
    // 输出最终结果
    for(i=0; i<12; ++i)
    {
        for(j=0; j<12; ++j)
            putchar(map[i][j]);
        printf("\n");
    }
}

int main(void)
{
    Solve(1, 2, 10, 9);
}


运行结果:
   *   *   *   *   *   *   *   *   *   *   *   *
   *   #   1   #   #   #   #   #   #   #   #   *
   *   #   2   #   6   7   8   9   #  15   #   *
   *   #   3   4   5   #   #  10   #  14   #   *
   *   #   4   #   #   #   #  11  12  13   #   *
   *   #   5   #   #   #   #   #   #   #   #   *
   *   #   6   7   8   9  10  11  12  13   #   *
   *   #   7   #   #   #  11   #  13   #   #   *
   *   #   8   #   #   #  12   #  14   #   #   *
   *   #   9   #  15  14  13   #  15  16   #   *
   *   #  10   #   #   #   #   #   #  17   #   *
   *   *   *   *   *   *   *   *   *   *   *   *
************
*#o########*
*#o#    # #*
*#o  ## # #*
*#o####   #*
*#o########*
*#ooooooo #*
*# ### #o##*
*# ### #o##*
*# #   #oo#*
*# ######o#*
************

74 楼

13. 有N个硬币(N为偶数)正面朝上排成一排,每次将 N-1 个硬币翻过来放在原位
 置, 不断地重复上述过程,直到最后全部硬币翻成反面朝上为止。编程让计算机把
 翻币的最简过程及翻币次数打印出来(用*代表正面,0代表反面)。

13.解答:
// 一共需要翻n次,每次都有一枚不翻转,但这一枚是不重复的
#include<stdio.h>
#define MAX 50
int Solve(int n)
{
    int i,j;
    int state[MAX] = {0};    // 记录硬币状态,state[i]=0表示第i枚硬币是正面向上
    // 输出初始状态
    for(j=0;j<n;++j)
        putchar(state[j]?'0':'*');
    putchar('\n');
    for(i=0;i<n;++i)    // 一共翻50次
    {
        for(j=0;j<i;++j)
            state[j] = !state[j];    // 翻转i以前的
        for(j=i+1;j<n;++j)
            state[j] = !state[j];    // 翻转i以后的
        // 如此,只有第i枚没翻转
        // 现在输出当前状态
        for(j=0;j<n;++j)
            putchar(state[j]?'0':'*');
        putchar('\n');
    }
}

int main(void)
{
    int n;
    scanf("%d",&n);
    Solve(n);
}

75 楼

14. 有黑白棋子各有N个(分别用*和0代替),按下图方式排列

        ***...***000...000

         N个黑棋    N个白棋

 允许将相邻两个棋子互换位置,最后使队形成黑白交替排列,试编程实现该操作。

14.解答:
// 一共需要翻n次,每次都有一枚不翻转,但这一枚是不重复的
#include<stdio.h>
#define MAX 20

char state[MAX*2+1];

// Move
// 把第end位置的棋子交换到第start位置
// 其他棋子依次向后移动一个位置
void Move(int start, int end)
{
    while( end > start )
    {
        int tmp = state[end];
        state[end] = state[end-1];
        state[end-1] = tmp;
        puts(state);
        --end;
    }
}

int Solve(int n)
{
    int i;
    puts(state);
    for(i=1;i<n;++i)
        Move(i*2-1,n+i-1);
}

int main(void)
{
    int i,n;
    scanf("%d",&n);
    for(i=0;i<n;++i)
        state[i] = '*';
    for(i=n;i<n*2;++i)
        state[i] = '0';
    state[i] = '\0';
    Solve(n);
}

76 楼

//第一题解答
//从算式中可看出 G = 0  F = 5
//则其余 8 个属于集合 {1,2,3,4,6,7,8,9}
//生成该集合的所有排列再进行判断,利用 bExit 标志在获取结果后及时终止
//排列生成使用递归

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

enum Table {A, B, C, D, E, X, Y, Z};

void Compute(int List[], int First, int Last)
{
    static bool bExit;
    
    if(bExit)
        return;

    if(First == Last)
    {
        int Tmp = 1 + List[C] + 2 * List[D];
        if(Tmp % 10 != List[Z])
            return;
        Tmp = Tmp/10;
        if((List[B] + Tmp)%10 != List[Y])
            return;
        if(List[X] != List[A] + (List[B] + Tmp)/10)
            return;

        bExit = true;
        cout<<List[A]<<List[B]<<List[C]<<List[D]<<List[E]<<endl
            <<"  "<<List[D]<<5<<0<<endl
            <<"+ "<<List[D]<<5<<0<<endl
            <<"-----"<<endl
            <<List[X]<<List[Y]<<List[Z]<<List[D]<<List[E]<<endl;

    }
    else
        for(int i = First; i <= Last; ++i)
        {
            std::swap(List[First], List[i]);
            Compute(List, First + 1, Last);

            if(bExit)
                return;

            std::swap(List[First], List[i]);
        }
}

int main()
{
    int List[8] = {1, 2, 3, 4, 6, 7, 8, 9};
    Compute(List, 0, 7);
    return 0;
}


//第二题解答
//思路和eastcowboy一样,别说我抄袭
#include<iostream>
#include<iomanip>
using namespace std;

enum {A, B, C, D, E};

bool Test(int Src, int Bit)
{
    return (Src & (1<<Bit)) != 0;
}

int main()
{
    char Table[] = "ABCDE";

    for(int x = 1; x <= 32; ++x)
    {
        if(Test(x, A) && !Test(x, B))
            continue;
        if(Test(x, B) && Test(x, C))
            continue;
        if(Test(x, C) != Test(x, D))
            continue;
        if(!Test(x, D) && !Test(x, E))
            continue;
        if(Test(x, E) && !(Test(x, A) && Test(x, D)))
            continue;

        for(int y = 0; y < 5; ++y)
        {
            if(Test(x, y))
                cout<<Table[y];
        }
        cout<<endl;
    }

    return 0;
}


#include <iostream>
using namespace std;
//第三题解答
//总觉得这题用递归比较好解决,于是...
//递归绘图
void _Draw(int First, int Last, const char* Fill, int Size)
{
    static char* DataPtr;
    char* Tmp = new char[Size+1];

    if(DataPtr)
        memcpy(Tmp, DataPtr, Size+1);
    else
        Tmp[Size] = 0;
    DataPtr = Tmp;

    if(First > Last)
        return;

    for(int i = First; i <= Last; ++i)
        Tmp[i] = Fill[First];
    puts(Tmp);

    if(First == Last)
        return;

    _Draw(First+1, Last-1, Fill, Size);
    puts(Tmp);

    delete [] Tmp;
}

inline
void Draw(const char* Fill, int Size)
{
    return _Draw(0, Size-1, Fill, Size);
}

int main()
{
    const char Fill[] = "TJ12345678";
    int n;
    if(cin>>n && n > 3 && n < 20)
        Draw(Fill, n);
    return 0;
}


//第四题解答
//还不能理解什么是拉丁方阵
//位置暂留


//第五题解答
//只支持正整数的数制转换
#include <iostream>
#include <cassert>
using namespace std;

char* DecToX(char* Dst, int Src, int Base)
{
    assert(Dst);
    assert(Base > 0);

    char Table[] = "0123456789ABCDEF";
    char Buffer[sizeof(int)*8 + 1] = {0};
    char* Ptr = Buffer;
    char* Dest = Dst;
    while(Src)
    {
        *Ptr++ = Table[Src%Base];
        Src/=Base;
    }
    while(--Ptr >= Buffer)
        *Dest++ = *Ptr;
    *Dest = 0;

    return Dst;
}

int main()
{
    char Buffer[sizeof(int)*8+1];
    int  Num;
    int Base;
    if(cin>>Num && cin>>Base && Num > 0 && Base > 0 && Base <= 16)
        cout<<DecToX(Buffer, Num, Base);

    return 0;
}


//第六题解答
//位置暂留


//第七题解答
#include <iostream>
#include <algorithm>
#include <functional>
#include <string>
using namespace std;

void Reverse(char* First, char* Last)
{
    --Last;
    while(First < Last)
        swap(*First++, *Last--);
}

const char Delim = '%';

int main()
{
    string Tmp;
    char*  Buffer;
    if(getline(cin, Tmp, Delim))
    {
        Buffer = new char[Tmp.size() + 1];
        char* Last   = Buffer + Tmp.size();
        *Last = 0;
        Tmp.copy(Buffer, Tmp.size());

        char* SubFirst = Buffer;
        char* SubLast;

        do
        {
            SubFirst = find_if(SubFirst, Last, isalpha);
            SubLast  = find_if(SubFirst, Last, not1(ptr_fun(isalpha)));
            if(SubFirst != SubLast && (*SubFirst == 'A' || *(SubLast-1) == 'N'))
                Reverse(SubFirst, SubLast);
        }while((SubFirst = SubLast) != Last);

        cout<<Buffer<<endl;
        delete [] Buffer;
    }
    return 0;
}

77 楼

// 40以内的素数表
int PrimeTable[] = {2,3,5,7,11,13,17,19,23,29,31,37};
// 函数IsPrime,判断一个数是否为素数,若是,返回1,否则返回0
// 实现:采用二分查找法,在PrimeTable数组中进行查找
int IsPrime(int n)
{
    int low = 0;
    int high = 12;    // 40以内的素数共12个
    while( low <= high )
    {
        int mid = (low+high)/2;
        if( PrimeTable[mid] == n )
            return 1;
        else if( PrimeTable[mid] > n )
            high = mid-1;
        else
            low = mid+1;
    }
    return 0;
}


这个不需要
直接 初始化一次
prim[i] 数组 
prim[i] = 1 i是 素数
prim[i] = 0 i 不是素数

反正可能的和不多

78 楼

/*******************************************************************************
9. 四人玩火柴棍游戏,每一次都是三个人赢,一个人输。输的人要按赢者手中的火柴
  数进行赔偿,即赢者手中有多少根火柴棍,输者就赔偿多少根。现知道玩过四次后,
  每人恰好输过一次, 而且每人手中都正好有16根火柴。问此四人做游戏前手中各有
  多少根火柴? 编程解决此问题。
********************************************************************************/
//逆推法   
#include <stdio.h>
void tran(int *,int);
void main()
{
    int arr[4]={16,16,16,16};//最后一次各玩家的棍数
     for (int i=0;i<4;i++)
    {
        tran(&arr[0],i);   //每人输一次
    }
    for(i=0;i<4;i++)
        printf("%d   ",arr[i]);
    printf("\n");
}
void tran(int *a,int b)
{
    int *pa,*pb,n;
    pa=a;
    pb=(a+b);
    for (n=0;n<4;n++)
    {
        if (pa != pb)    //输的玩家加上其它各玩家棍数的一半,赢得减去一半
        {
            (*pb)+=(*pa)/2;
            (*pa)-=(*pa)/2;
        }
        pa++;
    }
}

79 楼

弓虽!

80 楼

15. 已知6个城市,用c[i,j]表示从i城市到城市j是否有单向的直达汽车

 (1=<i〈=6,1〈=j〈=6), c[i,j]=1 表示城市i到城市j有单向直达汽
 车; 否则 c[i,j]=0.  试编制程序,对于给出的城市代号i,打印出从该城市出
 发乘车(包括转车)可以到达的所有城市。

15.解答
地图是自己设置的,采用深度优先搜索

#include <stdio.h>
#define N 6

int C[N+1][N+1] =    // 下标为0的元素是不使用的
// 首先,令C[i][i] = 1,即左上到右下对角线上值为1,表示所有城市可到达自己本身
// 假设1可到2,3,4,2可到1,3,6,3可到1,2,4,4可到2,3,6,5可到2,3,4,6可到1,2,3,
// 程序运行时:
// 输入:1或2或3或4或6
// 结果:1,2,3,4,6
// 输入:5
// 结果:1,2,3,4,5,6
{
    -1,-1,-1,-1,-1,-1,-1,
    -1, 1, 1, 1, 1, 0, 0,
    -1, 1, 1, 1, 0, 0, 1,
    -1, 1, 1, 1, 1, 0, 0,
    -1, 0, 1, 1, 1, 0, 1,
    -1, 0, 1, 1, 1, 1, 0,
    -1, 1, 1, 1, 0, 0, 1
};

int visited[N+1] = {0};    // 下标为0的元素是不使用的

void visit(int i)
{
    int j;
    if( visited[i] )
        return;
    visited[i] = 1;
    for(j=1; j<=N; ++j)
        if(C[i][j]==1)
            visit(j);
}

int main(void)
{
    int i;
    scanf("%d",&i);
    visit(i);
    for(i=1; i<=N; ++i)
        if(visited[i])
            printf("%4d",i);
    printf("\n");
}

我来回复

您尚未登录,请登录后再回复。点此登录或注册