当前位置:   article > 正文

答案解析——蓝桥杯2014年省赛大学B组真题 C/C++_四、大杯饮料一杯5元,中杯饮料一杯3元,小杯饮料一杯0.5元,编程实现100元买100

四、大杯饮料一杯5元,中杯饮料一杯3元,小杯饮料一杯0.5元,编程实现100元买100

啤酒和饮料【结果填空题】T-1

啤酒每罐2.3元,饮料每罐1.9元。小明买了若干啤酒和饮料,一共花了82.3元。 我们还知道他买的啤酒比饮料的数量少,请你计算他买了几罐啤酒。 注意:答案是一个整数。请通过浏览器提交答案。 不要书写任何多余的内容(例如:写了饮料的数量,添加说明文字等)。

  1. //C++
  2. //思路:枚举
  3. #include<iostream>
  4. using namespace std ;
  5. int main()
  6. {
  7.    for(int i = 1; i <= 50; ++i)
  8.   {
  9.        for (int j = 1; j <= 60; ++j)
  10.       {
  11.            if(2.3*i+1.9*j==82.3 && i<j)
  12.                cout << i << " " << j << endl ;
  13.       }
  14.   }
  15.    return 0 ;
  16. }
  17. //输出:11 30

切面条【结果填空题】T-2

一根高筋拉面,中间切一刀,可以得到2根面条。 如果先对折1次,中间切一刀,可以得到3根面条。 如果连续对折2次,中间切一刀,可以得到5根面条。 那么,连续对折10次,中间切一刀,会得到多少面条呢? 答案是个整数,请通过浏览器提交答案。不要填写任何多余的内容。

  1. /*找规律
  2. 条数:2 3 5 9 17   .... 1014+1
  3. 折数:0 1 2 3 4   .... 10 */
  4. //答案 1025 2^10+1

李白打酒【结果填空题】T-3

题目:李白打酒 话说大诗人李白,一生好饮。幸好他从不开车。 一天,他提着酒壶,从家里出来,酒壶中有酒2斗。他边走边唱: 无事街上走,提壶去打酒。 逢店加一倍,遇花喝一斗。 这一路上,他一共遇到店5次,遇到花10次, 已知最后一次遇到的是花,他正好把酒喝光了。 请你计算李白遇到店和花的次序,可以把遇店记为a, 遇花记为b。则:babaabbabbabbbb 就是合理的次序。 像这样的答案一共有多少呢? 请你计算出所有可能方案的个数(包含题目给出的)。 注意:通过浏览器提交答案。答案是个整数。不要书写任何多余的内容。

  1. //深搜
  2. #include<iostream>
  3. using namespace std;
  4. int ans;
  5. void f(int dian, int hua, int jiu)
  6. {
  7.    if (dian == 0 && hua == 0 && jiu == 1) ans++;
  8.    if (dian > 0) f(dian - 1, hua, jiu * 2);
  9.    if (hua > 0) f(dian, hua - 1, jiu - 1);
  10. }
  11. int main()
  12. {
  13.    f(5, 9, 2);
  14.    cout << ans << endl;
  15.    return 0;
  16. }
  17. // ans: 14

史丰收速算【代码填空题】T-4

史丰收速算法的革命性贡献是:从高位算起,预测进位。 不需要九九表,彻底颠覆了传统手算! 速算的核心基础是:1位数乘以多位数的乘法。 其中,乘以7是最复杂的,就以它为例。 因为,1/7 是个循环小数:0.142857...,如果多位数超过 142857..., 就要进1同理,2/7, 3/7, ... 6/7 也都是类似的循环小数, 多位数超过 n/7,就要进n 下面的程序模拟了史丰收速算法中乘以7的运算过程。 乘以 7 的个位规律是:偶数乘以2,奇数乘以2再加5,都只取个位。 乘以 7 的进位规律是:

满 142857... 进1,
满 285714... 进2,
满 428571... 进3,
满 571428... 进4,
满 714285... 进5,
满 857142... 进6.

请分析程序流程,填写划线部分缺少的代码。

  1. #include<iostream>
  2. using namespace std ;
  3. //计算个位
  4. int ge_wei(int a)
  5. {
  6.    if(a % 2 == 0) //偶数
  7.        return (a * 2) % 10; //乘以2保留个位
  8.    else //奇数
  9.        return (a * 2 + 5) % 10; //乘以2加上5保留个位
  10. }
  11. //计算进位
  12. int jin_wei(char* p) //计算进位
  13. {
  14.    char* level[] = {
  15.        "142857",
  16.        "285714",
  17.        "428571",
  18.        "571428",
  19.        "714285",
  20.        "857142"
  21.   };//如果多位数超过n/7,就要进n
  22.    
  23.    char buf[7];
  24.    buf[6] = '\0';
  25.    strncpy(buf,p,6); //将p这个字符串,拷贝到buff中
  26.    
  27.    int i;
  28.    for(i=5; i>=0; i--){
  29.        int r = strcmp(level[i], buf); //从后往前,一次level中的串和buff比较
  30.        if(r<0) return i+1; //buf更大,得出进位数=i+1
  31.        while(r==0){ //buf和level[i]相同
  32.            p += 6; //往后偏移6位
  33.            strncpy(buf,p,6); //再拷贝6个字符到buf中
  34.            r = strcmp(level[i], buf); //再比较
  35.            if(r<0) return i+1;  //buf更大
  36.            /*此处为代码填空处
  37.            //buf更小
  38.            if(r>0)
  39.            {
  40.                return i ; //
  41.                //测试:cout << i << " " << endl ;
  42.            }
  43.            */
  44.       }
  45.   }
  46.    
  47.    return 0;
  48. }
  49. //多位数乘以7
  50. void f(char* s) //s代表多位数
  51. {
  52.    int head = jin_wei(s); //head是s的进位
  53.    if(head > 0) printf("%d", head); //输出进位
  54.    
  55.    char* p = s; //拷贝字符串指针
  56.    while(*p){ //没有到末尾
  57.        int a = (*p-'0'); //依次取字符转数字
  58.        int ge = ge_wei(a) ; //算出个位
  59.        int x = (ge_wei(a) + jin_wei(p+1)) % 10;
  60.        printf("%d",x); //打印
  61.        p++; //指针后移
  62.   }
  63.    
  64.    printf("\n");
  65. }
  66. int main()
  67. {
  68.    f("428571428571");
  69.    f("34553834937543");        
  70.    return 0;
  71. }

打印图形【代码填空题】T-5

  1. 小明在X星球的城堡中发现了如下图形和文字:
  2. rank=3
  3.   *
  4. * *
  5. *   *  
  6. * * * *
  7. rank=5
  8.               *                                                      
  9.             * *                                                    
  10.             *   *                                                    
  11.           * * * *                                                  
  12.           *       *                                                  
  13.         * *     * *                                                
  14.         *   *   *   *                                                
  15.       * * * * * * * *                                              
  16.       *               *                                              
  17.     * *             * *                                            
  18.     *   *           *   *                                            
  19.   * * * *         * * * *                                          
  20.   *       *       *       *  
  21. * *     * *     * *     * *  
  22. *   *   *   *   *   *   *   *
  23. * * * * * * * * * * * * * * * *  
  24. ran=6
  25.                               *                                      
  26.                             * *                                    
  27.                             *   *                                    
  28.                           * * * *                                  
  29.                           *       *                                  
  30.                         * *     * *                                
  31.                         *   *   *   *                                
  32.                       * * * * * * * *                              
  33.                       *               *                              
  34.                     * *             * *                            
  35.                     *   *           *   *                            
  36.                   * * * *         * * * *                          
  37.                   *       *       *       *                          
  38.                 * *     * *     * *     * *                        
  39.                 *   *   *   *   *   *   *   *                        
  40.               * * * * * * * * * * * * * * * *                      
  41.               *                               *                      
  42.             * *                             * *                    
  43.             *   *                           *   *                    
  44.           * * * *                         * * * *                  
  45.           *       *                       *       *                  
  46.         * *     * *                     * *     * *                
  47.         *   *   *   *                   *   *   *   *                
  48.       * * * * * * * *                 * * * * * * * *              
  49.       *               *               *               *              
  50.     * *             * *             * *             * *            
  51.     *   *           *   *           *   *           *   *            
  52.   * * * *         * * * *         * * * *         * * * *          
  53.   *       *       *       *       *       *       *       *          
  54. * *     * *     * *     * *     * *     * *     * *     * *        
  55. *   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *        
  56. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *      
  57.                                                                      
  58. 小明开动脑筋,编写了如下的程序,实现该图形的打印。
  1. //C++
  2. #include<iostream>
  3. #define N 70
  4. void f(char a[][N], int rank, int row, int col) //设置限制和格式
  5. {
  6.    if (rank == 1) {
  7.        a[row][col] = '*';
  8.        return;
  9.   }
  10.    int w = 1;
  11.    int i;
  12.    for (i = 0; i < rank - 1; i++) w *= 2;
  13.    /*此处为代码填空处
  14.    f(a, rank-1, row, col+w/2); */ //处理顶上的三角形
  15.    f(a, rank - 1, row, col + w / 2);
  16.    f(a, rank - 1, row + w / 2, col); //a,5,16,0 处理左下角
  17.    f(a, rank - 1, row + w / 2, col + w);//a,5,16,16 处理右下角
  18. }
  19. int main()
  20. {
  21.    char a[N][N]; //初始化
  22.    int i, j;
  23.    for (i = 0; i < N; i++)
  24.        for (j = 0; j < N; j++) a[i][j] = ' ';
  25.    f(a, 6, 0, 0);
  26.    for (i = 0; i < N; i++) { //输出
  27.        for (j = 0; j < N; j++) printf("%c", a[i][j]);
  28.        printf("\n");
  29.   }
  30.    return 0;
  31. }

奇怪的分式【代码编程题】T-6

上小学的时候,小明经常自己发明新算法。一次,老师出的题目是: 1/4 乘以 8/5 小明居然把分子拼接在一起,分母拼接在一起,答案是:18/45 (参见图1.png) 老师刚想批评他,转念一想,这个答案凑巧也对啊,真是见鬼! 对于分子、分母都是 1~9 中的一位数的情况,还有哪些算式可以这样计算呢? 请写出所有不同算式的个数(包括题中举例的)。 显然,交换分子分母后,例如:4/1 乘以 5/8 是满足要求的,这算做不同的算式。 但对于分子分母相同的情况,2/2 乘以 3/3 这样的类型太多了,不在计数之列!

  1. //答案是个整数,考虑对称性,肯定是偶数
  2. //枚举加验证 最大公约数
  3. #include<iostream>
  4. using namespace std;
  5. int ans;
  6. int gcd(int a, int b) //最大公约数
  7. {
  8.    if (b == 0)
  9.        return a;
  10.    return gcd(b, a % b); //辗转相除
  11. }
  12. int main()
  13. {
  14.    cout << gcd(12, 16) << endl;
  15.    for (int a = 1; a < 10; ++a)
  16.   {
  17.        for (int b = 1; b < 10; ++b)
  18.       {
  19.            if (b == a) continue;
  20.            for (int c = 1; c < 10; ++c)
  21.           {
  22.                for (int d = 1; d < 10; ++d)
  23.               {
  24.                    if (c == d) continue;
  25.                    int g1 = gcd(a * c, b * d);
  26.                    int g2 = gcd(a * 10 + c, b * 10 + d);
  27.                    if (a * c / g1 == (a * 10 + c) / g2 && b * d / g1 == (b * 10 + d) / g2)
  28.                   {
  29.                        printf("%d %d %d %d\n", a, b, c, d);
  30.                        ans++;
  31.                   }
  32.               }
  33.           }
  34.       }
  35.   }
  36.    cout << ans << endl;
  37.    return 0;
  38. }

六角填数【结果填空题】T-7 

如图【1.png】所示六角形中,填入1~12的数字。

 

            (1)
    (8)  ()      ()  ()
      (*)          ()
    ()  ()       ()  ()      
            (3)                

使得每条直线上的数字之和都相同。 图中,已经替你填好了3个数字,请你计算星号位置所代表的数字是多少?

  1. //C++
  2. /*思路:*/
  3. #include<iostream>
  4. #include<vector>
  5. #include <algorithm>
  6. using namespace std;
  7. void check(vector<int> v);
  8. int main()
  9. {
  10. vector<int> v;
  11. v.push_back(2);
  12. for (int i = 4; i <= 7; ++i)
  13. {
  14. v.push_back(i);
  15. }
  16. for (int i = 9; i <= 12; ++i)
  17. {
  18. v.push_back(i);
  19. }
  20. do {
  21. check(v);
  22. } while (next_permutation(v.begin(), v.end()));
  23. return 0;
  24. }
  25. void check(vector<int> v)
  26. {
  27. int r1 = 1 + v[0] + v[3] + v[5];
  28. int r2 = 1 + v[1] + v[4] + v[8];
  29. int r3 = 8 + v[0] + v[1] + v[2];
  30. int r4 = 11 + v[3] + v[6];
  31. int r5 = 3 + v[2] + v[4] + v[7];
  32. int r6 = v[5] + v[6] + v[7] + v[8];
  33. if (r1 == r2 && r2 == r3 && r3 == r4 && r4 == r5 && r5 == r6)
  34. {
  35. for (int i = 0; i < 0; ++i)
  36. {
  37. cout << v[3] << " " << endl;
  38. }
  39. }
  40. }

蚂蚁感冒 【编程大题】T-8

长100厘米的细长直杆子上有n只蚂蚁。 ​ 它们的头有的朝左,有的朝右。 ​ 每只蚂蚁都只能沿着杆子向前爬,速度是1厘米/秒。 ​ 当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行。 ​ 这些蚂蚁中,有1只蚂蚁感冒了。 ​ 并且在和其它蚂蚁碰面时,会把感冒传染给碰到的蚂蚁。 ​ 请你计算,当所有蚂蚁都爬离杆子时,有多少只蚂蚁患上了感冒。

【数据格式】 第一行输入一个整数n (1 < n < 50), 表示蚂蚁的总数。 接着的一行是n个用空格分开的整数 Xi (-100 < Xi < 100), Xi的绝对值,表示蚂蚁离开杆子左边端点的距离。 正值表示头朝右,负值表示头朝左,数据中不会出现0值, 也不会出现两只蚂蚁占用同一位置。 其中,第一个数据代表的蚂蚁感冒了。 要求输出1个整数,表示最后感冒蚂蚁的数目。

例如,输入: 3 5 -2 8 程序应输出:1

再例如,输入: 5 -10 8 -20 12 25 程序应输出:3

资源约定: 峰值内存消耗 < 256M CPU消耗 < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。 所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。 注意: main函数需要返回0 注意: 只使用ANSI C/ANSI C++ 标准,不 要调用依赖于编译环境或操作系统的特殊函数。 注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

提交时,注意选择所期望的编译器类型。

  1. /*
  2. 同向蚂蚁:前面的追不上
  3. 反向蚂蚁:相遇*/
  4. //C++
  5. #include<iostream>
  6. #define scanf scanf_s
  7. using namespace std;
  8. int main()
  9. { //输入
  10. int n;
  11. scanf("%d", &n);
  12. int arr[50]; //数组存放数据
  13. //搜索
  14. for (int i = 0; i < n; ++i)
  15. {
  16. scanf("%d", &arr[i]);
  17. }
  18. //定义蚂蚁位置
  19. int x = arr[0];
  20. if (x > 0) //向右
  21. {
  22. int ans = 1; //感冒的蚂蚁
  23. //扫描所有蚂蚁
  24. for (int i = 0; i < n; ++i)
  25. {
  26. if (arr[i]<0 && -arr[i]>x) //从右向左
  27. ans++;
  28. }
  29. if (ans != 1) //有从右向左的
  30. for (int i = 0; i < n; ++i)
  31. {
  32. //找跟在后面的
  33. if (arr[i] > 0 && arr[i] < x) //
  34. ans++;
  35. }
  36. printf("%d\n", ans);
  37. }
  38. if (x < 0) //向左
  39. {
  40. //左侧从左到右
  41. int ans = 1;
  42. for (int i = 0; i < n; ++i)
  43. if (arr[i] > 0 && arr[i] < -x)
  44. ans++;
  45. if (ans != 1)
  46. for (int i = 0; i < n; ++i)
  47. {
  48. if (arr[i]<0 && -arr[i]>-x)
  49. ans++;
  50. }
  51. printf("%d\n", ans);
  52. return 0;
  53. }
  54. }

地宫取宝【代码编程题】T-9

X 国王有一个地宫宝库。是 n x m 个格子的矩阵。 每个格子放一件宝贝。每个宝贝贴着价值标签。 地宫的入口在左上角,出口在右下角。 小明被带到地宫的入口,国王要求他只能向右或向下行走。 走过某个格子时,如果那个格子中的宝贝价值比小明手中任意宝贝 价值都大,小明就可以拿起它(当然,也可以不拿)。 当小明走到出口时,如果他手中的宝贝恰好是k件, 则这些宝贝就可以送给小明。请你帮小明算一算, 在给定的局面下,他有多少种不同的行动方案能获得这k件宝贝。

【数据格式】 输入一行3个整数,用空格分开:n m k (1<=n,m<=50, 1<=k<=12) 接下来有 n 行数据,每行有 m 个整数 Ci (0<=Ci<=12) 代表这个格子上的宝物的价值 要求输出一个整数,表示正好取k个宝贝的行动方案数。 该数字可能很大,输出它对 1000000007 取模的结果。

例如,输入: 2 2 2 1 2 2 1 程序应该输出:2

再例如,输入: 2 3 2 1 2 3 2 1 5 程序应该输出:14

资源约定: 峰值内存消耗 < 256M CPU消耗 < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。 所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。 注意: main函数需要返回0 注意: 只使用ANSI C/ANSI C++ 标准, 不要调用依赖于编译环境或操作系统的特殊函数。 注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。 提交时,注意选择所期望的编译器类型。

  1. //地宫取宝
  2. //深搜 递归取模
  3. #include<iostream>
  4. #include<cstring>
  5. using namespace std ;
  6. const int MOD = 10000007 ;
  7. int n,m,k ; //
  8. int data[50][50] ;
  9. long long ans ;
  10. long long cache[50][50][14][13]
  11. void dfs(int x,int y,int max,int cnt)
  12. {
  13. if(x==n || y==m || cnt > k) //cnt > k 剪枝
  14. return ;
  15. int cur = data[x][y] ;
  16. if(x==n-1 && y == m-1) //已经面临最后一个格子
  17. {
  18. if(cnt==k || (cnt==k-1 && cur>max))
  19. {
  20. ans++ ;
  21. if(ans>MOD) ans%=MOD ;
  22. }
  23. }
  24. //记忆型递归
  25. long long dfs2(int x,int y,int max,int cnt)
  26. {
  27. //查缓存
  28. if(cache[x][y][max+1][cnt]!=-1) return cache[x][y][max+1][cnt] ;
  29. long long ans = 0 ;
  30. if(x==n || y==m || cnt > k) //cnt > k 剪枝
  31. return ;
  32. int cur = data[x][y] ;
  33. if(x==n-1 && y == m-1) //已经面临最后一个格子
  34. {
  35. if(cnt==k || (cnt==k-1 && cur>max))
  36. {
  37. ans++ ;
  38. if(ans>MOD) ans%=MOD ;
  39. }
  40. }
  41. }
  42. if(cur > max)//可以取这个物品
  43. {
  44. ans += dfs(x,y+1,cur,cnt+1) ;
  45. ans += dfs(x+1,y,cur,cnt+1) ;
  46. }
  47. //对于价值较小,或者价值大但不去这个物品的情况如下
  48. ans += dfs(x,y+1,max,cnt) ;
  49. ans += dfs(x+1,y,max,cnt) ;
  50. ans += dfs2(x,y + 1,cur,cnt) ;
  51. ans += dfs2(x + 1,y,max,cnt) ;
  52. //写缓存
  53. return ans % MOD ;
  54. }
  55. int main()
  56. {
  57. scanf("%d %d %d",&n,&m,&k) ; //
  58. //
  59. for (int i = 0; i < n; ++i)
  60. {
  61. for (int j = 0; j < m; ++j)
  62. {
  63. scanf("%d",&data[i][j]) ;
  64. }
  65. }
  66. dfs(0,0,-1,0) ; //第一个点的价值可能是0
  67. dfs2(0,0,-1,0) ;//
  68. memset(cache,-1,sizeof) ;
  69. printf("%d\n",dfs2(0,0,-1,0)) ;
  70. return 0 ;
  71. }
  72. /*
  73. 解决重复子问题的求解:
  74. 动态规划:记忆性递归
  75. */

小朋友排队【代码编程题】T-10

n 个小朋友站成一排。现在要把他们按身高从低到高的顺序排列, 但是每次只能交换位置相邻的两个小朋友。 每个小朋友都有一个不高兴的程度。 开始的时候,所有小朋友的不高兴程度都是0。 如果某个小朋友第一次被要求交换,则他的不高兴程度增加1, 如果第二次要求他交换,则他的不高兴程度增加2 (即不高兴程度为3),依次类推。 当要求某个小朋友第k次交换时,他的不高兴程度增加k。 请问,要让所有小朋友按从低到高排队, 他们的不高兴程度之和最小是多少。 如果有两个小朋友身高一样,则他们谁站在谁前面是没有关系的。

【数据格式】 输入的第一行包含一个整数n,表示小朋友的个数。 第二行包含 n 个整数 H1 H2 … Hn,分别表示每个小朋友的身高。 输出一行,包含一个整数,表示小朋友的不高兴程度和的最小值。

例如,输入: 3 3 2 1 程序应该输出: 9

【样例说明】 首先交换身高为3和2的小朋友,再交换身高为3和1的小朋友, 再交换身高为2和1的小朋友,每个小朋友的不高兴程度都是3,总和为9。

【数据规模与约定】 对于10%的数据, 1<=n<=10; 对于30%的数据, 1<=n<=1000; 对于50%的数据, 1<=n<=10000; 对于100%的数据,1<=n<=100000,0<=Hi<=1000000。

资源约定: 峰值内存消耗 < 256M CPU消耗 < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。 所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。 注意: main函数需要返回0 注意: 只使用ANSI C/ANSI C++ 标准, 不要调用依赖于编译环境或操作系统的特殊函数。 注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

提交时,注意选择所期望的编译器类型。 ————————————————————————————————————————————————————————————*/

  1. //
  2. /*
  3. 1. 前缀和数组(静态数组)
  4. 2. 树状数组 C[k] (某个区间的和)[k-lowbi(k),x]
  5. lowbit(k)是k进制中最后一个1代表的整数
  6. B(6)->b(10)
  7. C6 sum(4,6)
  8. index 改动为 index + lowbit(index) */
  9. /**
  10. * 原始数组的i位置增加v后,更新C数组
  11. * n 边界
  12. * i 初始值
  13. * v
  14. * c
  15. */
  16. //树状数组的模板
  17. #include<iostream>
  18. #include<cstring>
  19. int lowbit(int k)
  20. {
  21.    return n-(n&(n-1)) ;    
  22. }
  23. void updata(int,int i,int v,int[]c)
  24. {
  25.    //int lb = Lowbit(i) ;
  26.    for (int k = i; k <= n; k+=Lowbit(k))
  27.   {
  28.        c[k] += v ;
  29.   }
  30. }
  31. int getSum(int c[],int i)
  32. {
  33.    int sum = 0 ;
  34.    for (int k = i; k >= 1; k-=lowbit(k))
  35.   {
  36.        sum+=c[k] ;
  37.   }
  38.    return sum ;
  39. }
  40. int main(int argc, char const *argv[])
  41. {
  42.    int arr[] = {1,2,3,4,5,6,7,8} ;
  43.    int c[9] ;
  44.    for (int i = 0; i < 8; ++i)
  45.   {
  46.        updata(9,i+1,arr[i],c) ;
  47.   }
  48.    cout << getSum(c,5) << endl ;
  49.    cout << getSum(c,6) << endl ;
  50.    cout << getSum(c,7) - getSum(c,4) << endl ;
  51.    return 0;
  52. }
  53. //解
  54. /*
  55. 3 2 1 |
  56. 2 3 1 |
  57. 2 1 3 |
  58. 1 2 3 |
  59. for 对每一位右侧更小
  60. 1. h ——> 树状数组的下标
  61. 2. a ——> 计数 //
  62. 按顺序为身高计数 如3加入 则a[3] = 1
  63. 由此统计sum3=1 证明<=3的个数为1
  64. 2加入 sum2 =1 总数=2
  65. 说明此前加入且比2大的个数为1
  66. 1加入 sum1=1 总数=3
  67. 说明此前加入且比1大的个数为1
  68. */
  69. #include <iostream>
  70. #include <cstring>
  71. #include <cstdio>
  72. using namespace std;
  73. int lowbit(int n) {
  74.    return n - (n & (n - 1));
  75. }
  76. /**
  77. * 原始数组的i位置增加v后,更新c数组
  78. * @param i
  79. * @param v
  80. * @param c
  81. */
  82. void updata(int n, int i, int v, int c[])
  83. {
  84.    for (int k = i; k <= n; k += lowbit(k))
  85.   {
  86.        c[k] += v;
  87.   }
  88. }
  89. int getSum(int c[], int i)
  90. {
  91.    int sum = 0;
  92.    for (int k = i; k >= 1; k -= lowbit(k))
  93.   {
  94.        sum += c[k];
  95.   }
  96.    return sum;
  97. }
  98. int h[100000];
  99. long long cnt[100000];//记录每个孩子的交换次数
  100. int c[1000000 + 1];
  101. int main(int argc, const char *argv[]) {
  102. //   int arr[]={1,2,3,4,5,6,7,8};
  103. //   int c[9];
  104. //   memset(c,0, sizeof(c));
  105. //   for (int i = 0; i < 8; ++i) {
  106. //       updata(9,i+1,arr[i],c);
  107. //   }
  108. //   cout<<getSum(c,5)<<endl;
  109. //   cout<<getSum(c,6)<<endl;
  110. //   cout<<getSum(c,7)-getSum(c,4)<<endl;
  111. //   freopen("/Users/zhengwei/Desktop/其他/input8 (1).txt", "r", stdin);
  112.    int n;
  113.    scanf("%d", &n);
  114. //   memset(cnt,0,sizeof(cnt));
  115.    int maxH = -1;
  116.    for (int i = 0; i < n; ++i)
  117.   {
  118.        scanf("%d", &h[i]);
  119.        if (h[i] > maxH)maxH = h[i];
  120.   }
  121.    for (int i = 0; i < n; ++i)
  122.   {
  123.        updata(maxH + 1, h[i] + 1, 1, c);//在响应位置计数变为1,其实就是用树状数组维护数据出现的个数
  124.        //
  125.        int sum = getSum(c, h[i] + 1);//小于等于h[i]+1的数据的个数
  126.        cnt[i] += (i + 1) - sum;//得到的就是当前数据左侧比数据大的数的个数
  127.   }
  128.    memset(c, 0, sizeof(c));
  129.    for (int i = n - 1; i >= 0; --i) {
  130.        updata(maxH + 1, h[i] + 1, 1, c);
  131.        //在响应位置计数变为1,其实就是用树状数组维护数据出现的个数
  132. //       int sum = getSum(c, h[i] + 1);//小于等于h[i]+1的数据的个数
  133. //       int self = getSum(c,h[i]+1)-getSum(c,h[i]);
  134. //       cnt[i] += sum-self;//上一步求出小于等于h的个数,扣掉自己的个数,得到的就是当前数据右侧比数据小的数的个数
  135.        cnt[i] += getSum(c, h[i]);//求出小于h[i]+1 的数据的个数
  136.   }
  137.    long long ans = 0;
  138.    for (int i = 0; i < n; ++i) {
  139.        ans += (cnt[i] * (cnt[i] + 1) / 2);
  140.   }
  141.    printf("%lli\n", ans);
  142.    return 0;
  143. }

【2014年省赛B组小结】

  1. /*************************************************************
  2. * 【2014年省赛B组小结】
  3. * 01【结果填空】啤酒与饮料:简单枚举
  4. *
  5. * 02【结果填空】切面条:思维,归纳,找规律
  6. *
  7. * 03【结果填空】李白打酒:递归所有的解
  8. *
  9. * 04【代码填空】史丰收速算:
  10. *
  11. * 05【代码填空】打印图形:递归 整体思维
  12. *
  13. * 06【代码填空】奇怪的分式:枚举+最大公约数
  14. *
  15. * 07【结果填空】六角填数:全排列
  16. *
  17. * 08【编程题】蚂蚁感冒:思维(穿过身体)
  18. *
  19. * 09【编程题】地宫取宝:搜索->记忆性递归
  20. *
  21. * 10【编程题】小朋友排队:树状数组
  22. * *****************************************************/

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/302655?site
推荐阅读
相关标签
  

闽ICP备14008679号