枚举,很暴力!

﹏ヽ暗。殇╰゛Y 2022-08-28 10:56 339阅读 0赞

坑爹的奥数

将数字 1~9 分别填入9个方框中,每个数字只能使用一次使等式成立。□□□+□□□=□□□!

  • 更好的实现方法:标记法!
    用一个 book 数组来解决互不相等的问题。

    include

    int main(){

    1. int a[10], i, total = 0;
    2. int book[10], sum;
    3. //这里可以用 a[1]~a[9] 来代替刚才的 a,b,c,d,e,f,g,h,i
    4. for (a[1] = 1; a[1] <= 9;a[1]++)
    5. for (a[2] = 1; a[2] <= 9;a[2]++)
    6. for (a[3] = 1; a[3] <= 9;a[3]++)
    7. for (a[4] = 1; a[4] <= 9;a[4]++)
    8. for (a[5] = 1; a[5] <= 9;a[5]++)
    9. for (a[6] = 1; a[6] <= 9;a[6]++)
    10. for (a[7] = 1; a[7] <= 9;a[7]++)
    11. for (a[8] = 1; a[8] <= 9;a[8]++)
    12. for (a[9] = 1; a[9] <= 9;a[9]++){
    13. for (i = 1; i <= 9;i++)
    14. //初始化 book 数组
    15. book[i] = 0;
    16. for (i = 1; i <= 9;i++)
    17. //如果某个值出现过就标记一次
    18. book[a[i]] = 1;
    19. sum = 0;
    20. //统计共出现了多少个不同的数
    21. for (i = 1;i <= 9;i++)
    22. sum += book[i];
    23. //如果正好出现了9个不同的数,并且满足等式条件,则输出
    24. if(sum==9&&a[i]*100+a[2]*10+a[3]+a[4]*100+a[5]*10+a[6]==a[7]*100+a[8]*10+a[9]){
    25. total++;
    26. printf("%d%d%d+%d%d%d=%d%d%d\n", a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]);
    27. }
    28. }
    29. printf("total=%d", total / 2);
    30. getchar();
    31. getchar();
    32. return 0;

    }

  • DFS

    include

    int a[10], book[10], total = 0;
    void dfs(int step){

    1. int i;
    2. if(step==10){
    3. if(a[1]*100+a[2]*10+a[3]+a[4]*100+a[5]*10+a[6]==a[7]*100+a[8]*10+a[9]){
    4. total++;
    5. printf("%d%d%d+%d%d%d=%d%d%d\n", a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]);
    6. }
    7. return;
    8. }
    9. for (i = 1; i <= 9;i++){
    10. if(book[i]==0){
    11. a[step] = i;
    12. book[i] = 1;
    13. dfs(step + 1);
    14. book[i] = 0;
    15. }
    16. }
    17. return;

    }
    int main(){

    1. dfs(1);
    2. printf("total=%d", total / 2);
    3. getchar();
    4. getchar();
    5. return 0;

    }

炸弹人的策略

  • 墙用 # 表示
  • 敌人用 G 表示
  • 空地用 . 表示

    #

    GG.GGG#GGG.

    .#G#G#G#G

    …….#..G

    G#.###.#G#G

    GG.GGG.#.GG

    G#.#G###.#G

    G…g…..

    G#.#G###.#G

    …G#GGG.GG

    G#.#G#G#.#G

    GG.GGG#G.GG

    #
  • 首先,需要一个二维字符数组来存储这个地图,至于将炸弹放置到哪一个点可以消灭的敌人最多,则需要一个个地来尝试。炸弹的爆炸方向是沿上下左右四个方向,因此我们在对每一个点进行枚举的时候,需要沿着上下左右四个方向分别统计可以消灭敌人的数目。最终输出可以消灭敌人最多的那个点。请注意这里是从0行0列开始时算的。

  • 如何分别统计上下左右四个方向上可以消灭的敌人数量呢?
  • 只要搞清楚一个方向,其他的方向都是一样的,这里就以向下统计为例。
  • 向下就是 y 不变,x 每次增加 1,直到遇到墙为止。

    include

    int main(){

    1. char a[20][21];
    2. int i, j;
    3. int sum, map = 0, p, q, x, y, n, m;
    4. //读入 n和 m表示有多少行字符,m表示每行有多少列
    5. scanf("%d %d", &n, &m);
    6. for (i = 0; i <= n - 1;i++)
    7. scanf("%s", a[i]);
    8. //用两重循环枚举地图中的每一个点
    9. for (i = 0; i <= n - 1;i++){
    10. for (j = 0; j <= m - 1;j++){
    11. //首先判断这个点是不是平地,是平地才能被放置炸弹
    12. if(a[i][j]=='.'){
    13. sum = 0;
    14. //sum 用来计数(可以消灭的敌人数),所以需要初始化为 0
    15. x = i;
    16. //将坐标 i,j 复制到两个新变量 x,y中,以便向上下左右四个方向分别统计可以消灭的敌人数
    17. //向上统计可以消灭的敌人数
    18. y = j;
    19. while(a[x][y]=='G'){
    20. //判断是不是墙,如果不是墙就继续
    21. if(a[x][y]=='G')
    22. //如果当前点是敌人,则进行计数
    23. sum++;
    24. x--;
    25. //继续向上统计
    26. }
    27. //向下统计可以消灭的敌人数
    28. x = i;
    29. y = j;
    30. while(a[x][y]!='#'){
    31. if(a[x][y]=='G')
    32. sum++;
    33. //继续向下统计
    34. x++;
    35. }
    36. //向左统计可以消灭的敌人数
    37. x = i;
    38. y = j;
    39. while(a[x][y]!='#'){
    40. if(a[x][y]!='G')
    41. sum++;
    42. y--;
    43. //继续向左统计
    44. }
    45. //向右统计可以消灭的敌人数
    46. x = i;
    47. y = j;
    48. while(a[x][y]!='#'){
    49. if(a[x][y]=='G')
    50. sum++;
    51. y++;
    52. //继续向右统计
    53. }
    54. //更新 map的值
    55. if(sum>map){
    56. //如果当前点所能消灭的敌人总数大于 map,则更新 map
    57. map = sum;
    58. //并用 p和 q记录当前点的坐标
    59. p = i;
    60. q = j;
    61. }
    62. }
    63. }
    64. }
    65. printf("将炸弹放置在(%d,%d),最多可以消灭%d个敌人\n", p, q, map);
    66. getchar();
    67. getchar();
    68. return 0;

    }


火柴棍等式

  • 注意
  • 加号与等式各自需要两根火柴棍
  • 如果 A!=B,则 A+B=C 与 B+A=C 视为不同的等式(A,B,C都大于0)
  • 所有根火柴棍必须全部用上

思路

  • 暴力枚举
    将枚举C改成通过 A+B 来算出 C,就将原来需要运行1000多秒的程序降低到了1秒。

    include

    int fun(int x){

    1. int num;
    2. int f[10] = { 6, 2, 5, 5, 4, 5, 6, 3, 7, 6};
    3. //用一个数组来记录 0~9每个数字需要用多少根火柴棍
    4. while(x/10!=0){
    5. //如果 x/10的商不等于 0的话,说明这个数至少有两位
    6. num += f[x % 10];
    7. //获得 x的末尾数字并将此数所需要的火柴棍累加到 num中
    8. x /= 10;
    9. //去掉 x的末尾数字,例如 x的值为 123,则现在 x的值为 12
    10. }
    11. num += f[x];
    12. return num;

    }

    int main(){

    1. int a, b, c, m, i, sum = 0;
    2. scanf("%d", &m);
    3. for (a = 0; a <= 1111;a++){
    4. for (b = 0; b <= 1111;b++){
    5. c = a + b;
    6. if(fun(a)+fun(b)+fun(c)==m-4){
    7. printf("%d+%d=%d\n", a, b, c);
    8. sum++;
    9. }
    10. }
    11. }
    12. printf("一共可以拼出%d个不同的等式", sum);
    13. getchar();
    14. getchar();
    15. return 0;

    }


数的全排列

案例:
123 的全排列
三重循环嵌套

  1. #include <stdio.h>
  2. int main(){
  3. int a, b, c;
  4. for (a = 1; a <= 3;a++){
  5. for (b = 1; b <= 3;b++){
  6. for (c = 1; c <= 3;c++){
  7. if(a!=b&&a!=c&&b!=c)
  8. printf("%d%d%d\n", a, b, c);
  9. }
  10. }
  11. }
  12. return 0;
  13. }

万能的搜索…

发表评论

表情:
评论列表 (有 0 条评论,339人围观)

还没有评论,来说两句吧...

相关阅读

    相关 ACM.暴力

    \有一类问题可以采用一种盲目的搜索方法,在搜索结果的过程中,把各种可能的情况都考虑到,并对所得的结果逐一进行判断,过滤掉那些不符合要求的,保留那些符合要求的,这种方法叫枚举算法

    相关 507 完美数(暴力

    1. 问题描述: 对于一个正整数,如果它和除了它自身以外的所有正因子之和相等,我们称它为 「完美数」。给定一个整数 n, 如果是完美数,返回 true,否则返回 false

    相关 暴力

    Problem Description 小埋今天出门准备买一堆漫画书回来,书的套餐类型有 3 种,第一种书是单本的,第二种书是两本捆在一起的,第三种是三本书捆在一起的。每