C 解决百度知道的一个高中题

前言

  今天看见一道百度知道上提问,是这样的.

仔细算了一下, 花了30min.才整出来了,估计现在回去参加高考,数学及格都悬.有时候想做这样的题有什么用,

学这些东西有什么意义,在这种方面浪费时间有什么值得的.

后来想出来,

    开心就好!

想太多,考虑太多心累.我们开心就好.

正文

  第一部分 从代码说开来

采用的主要思路是穷举法,穷举完之后,再判断. 思考了一下,主要用 char str[5]; 保存这个这个串. 采用下面函数检测这个串

是否是想要的串

#inclue <stdbool.h>

// 串检测函数
bool
isaa(char str[], int len)
{
    int i = 0;
    while(++i < len)
        if (str[i] == ‘a‘ && str[i - 1] == ‘a‘)
            return true;

    return false;
}

效率上也没深入搞了,追求能用就行了.

那怎么构建这个 char str[5] 呢. 这里原本采用 5层for,这直接pass了,首先一条准则, C程序开发一定要记住,或者程序员也要记住

1 /*
2   用不用goto取决你的业务复杂度
3
4  */
5
6 // 但是你一定不要用 超过三层的 循环,那种代码写出来后要打自己脸.

.后面采用 递归搞了一下, 如下

//采用递归算法穷举
void
dgaa(char str[],int len,int idx, int *psum, int *pcut)
{
    if (len > idx) {
        str[idx] = ‘a‘;
        dgaa(str, len, idx + 1, psum, pcut);

        str[idx] = ‘b‘;
        dgaa(str, len, idx + 1, psum, pcut);

        str[idx] = ‘c‘;
        return dgaa(str, len, idx + 1, psum, pcut);
    }
    ++*psum;
    *pcut += isaa(str, len);
}

最后需要 return,因为到这里就结束了,不能再往下了,否则重复计数了. 大家有好方法可以分享.

到这里一切都准备妥当了. 完整代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

// 串检测函数
bool isaa(char str[], int len);

//采用递归算法穷举
void dgaa(char str[], int len, int idx, int *psum, int *pcut);

/*
 上面函数的简化宏, 这里 用法是
 int psum = 0, pcut = 0;
 char str[5];
 int cut = DGAA(str);
 */
#define DGAA(str, sum, cut) \
    dgaa(str, sizeof(str)/sizeof(*str), 0, &sum, &cut)

/*
 * 这里处理一个问题
 *  一个由abc组成的五位字符串,至少包含 一个连续aa的串有多少个.
 *
 */
int main(int argc, char* argv[])
{
    int sum = 0, cut = 0;
    char str[5];
    DGAA(str, sum, cut);

    printf("所要找的所有串:%d个, 至少出现一次aa的串有 %d 个!\n",sum, cut);

    return 0;
}

// 串检测函数
bool
isaa(char str[], int len)
{
    int i = 0;
    while(++i < len)
        if (str[i] == ‘a‘ && str[i - 1] == ‘a‘)
            return true;

    return false;
}

//采用递归算法穷举
void
dgaa(char str[],int len,int idx, int *psum, int *pcut)
{
    if (len > idx) {
        str[idx] = ‘a‘;
        dgaa(str, len, idx + 1, psum, pcut);

        str[idx] = ‘b‘;
        dgaa(str, len, idx + 1, psum, pcut);

        str[idx] = ‘c‘;
        return dgaa(str, len, idx + 1, psum, pcut);
    }
    ++*psum;
    *pcut += isaa(str, len);
}

我们直接编译链接一下

gcc -g -Wall -o aa.out aa.c

总的运行结果如下:

答案是 至少出现一次aa的串有 79 个.

第二部分 从更高观点上分析这个问题

  采用思路就是简单的数学集合分析.

1) . abc 组成 长度为 5的串

    一共有 3^5 = 81 x 3 = 243

2) . 没有出现过 aa连续的串个数

  A) 串中没有a

    2^5 = 32

  B) 串中只有一个a

    首先剩下4个位置 2^4 = 16 后面 一个a 插入 到    x|x |x |x |x

    x的位置 有 C(1,5) = 5种,一共有 16 x 5 = 80种

  C) 串中有两个a  x | x | x | x 左边x的位置选出2个 插入 aa

    一共有 2^3 x C(4,2) = 8 x 4 x 3 / 2 = 48种

  D) 串中有3个 a  就是这样情况 a | a | a

    只有 2^2 = 4四种情况

  综上 A,B,C,D 一共有 32 + 80 + 48 + 4 = 112 + 52 = 164种

综上1) 2) 得到至少一个aa连续出现的5位串 个数为

  243 - 164 = 79 种

问题已经解决. 欢迎大家给出更巧妙的方法分享.

后记

  到这里说结束了, 错误是难免的,提出来一定改. 祝今天大家包括自己愉快, 以后的生活多一点行动,少一点

犹豫,关键是开心就好.O(∩_∩)O哈哈~

时间: 2024-12-14 12:08:36

C 解决百度知道的一个高中题的相关文章

2014百度之星资格赛第一题

Energy Conversion Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 11867    Accepted Submission(s): 2861 Problem Description 魔法师百小度也有遇到难题的时候-- 现在,百小度正在一个古老的石门面前,石门上有一段古老的魔法文字,读懂这种魔法文字需要耗费大量的能量和大

2014百度之星资格赛第二题

Disk Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2560    Accepted Submission(s): 366 Problem Description 有很多从磁盘读取数据的需求,包括顺序读取.随机读取.为了提高效率,需要人为安排磁盘读取.然而,在现实中,这种做法很复杂.我们考虑一个相对简单的场景.

解决百度云离线文件因含有违规内容被系统屏蔽无法下载问题

最近网上风声查的很严呀,好多视频都无法下载,一下载就提示  离线文件因含有违规内容被系统屏蔽无法下载,上次下载老外的视频教程都说是违规内容,忍无可忍,最近发现了一个神器,BTEditor ,应该算是种子文件编辑器吧,貌似能把那些被屏蔽的资源弄成可以离线下载的,网址   http://www.bteditor.com, 大家可以有空试试. 最近网上风声查的很严呀,好多视频都无法下载,一下载就提示  离线文件因含有违规内容被系统屏蔽无法下载,上次下载老外的视频教程都说是违规内容,忍无可忍,最近发现了

(关于一个算法题的两点新思路)给你一组字符串 如 {5,2,3,2,4,5,1,2,1,5},让你输出里面出现次数最多且数值最大的一个,出现几次

在网上看到一个算法题,不是很难,搜一下也有解决办法,但是一般都是几层for循环,试着写了下 /** * 给你一组字符串 如 {5,2,3,2,4,5,1,2,1,5},让你输出里面出现次数最多且数值最大的一个,出现几次 * 优点:时间复杂度为O(n) * 缺点:产生一些多余的空间,如 6,7,8没有的数也会分配一个数组空间,但是基本可以忽略 * 限制:需要预先知道最大的值是多少,或者说小于多少,这样才好确定预先分配一个数组长度是多少 */ public static void method1()

[转]解决百度统计 gzdecode(): insufficient memory

百度统计API gzdecode($preLogin->retData, strlen($preLogin->retData)) 这段代码会造成一个PHP警告内存不足,解决办法只要换个解压缩函数即可. gzdecode($preLogin->retData, strlen($preLogin->retData))  改成 gzinflate(substr($preLogin->retData,10,-8)) 即可. 来源: ->简单的解决 百度data API数据统计:

2014 百度之星第三题

Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total Submission(s): 0    Accepted Submission(s): 0 Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包括了N个正整数,随后 Prometheus 将向 Zeus 发起

2014百度之星第三题Xor Sum

Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total Submission(s): 4445    Accepted Submission(s): 652 Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Ze

2014百度之星第四题Labyrinth

Labyrinth Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1804    Accepted Submission(s): 626 Problem Description 度度熊是一只喜欢探险的熊,一次偶然落进了一个m*n矩阵的迷宫,该迷宫只能从矩阵左上角第一个方格开始走,只有走到右上角的第一个格子才算走出迷宫,每一次只能走一格

3个方法解决百度网盘限速 (2018-07-20)

360网盘关闭后,百度似乎要成为国内网盘的唯一选择,然而百度云下载速度太慢,显然是被限速了,吃相难看.下面有3个方法解决百度网盘限速的问题,演示的下载文件是大于1G的一个 War3.zip 单文件(用拖拽的方法打开,否则显示页面不存在),使用的宽带是电信20M,百度限速后的下载速度只有256KB/s,而理论上的下载速度是可以达到2M/s的.奶酪也将持续关注百度网盘限速的问题. 1. 百度网盘下载助手脚本 - 2018-04-15更新[最长久] 最早是网友"有一份田"制作的脚本百度下载助