2014年第五届蓝桥杯B组(C/C++)预赛题目及个人答案(欢迎指正)

来源:互联网 发布:sql语句修改表结构 编辑:程序博客网 时间:2024/05/25 19:57
1.标题:啤酒和饮料


    啤酒每罐2.3元,饮料每罐1.9元。小明买了若干啤酒和饮料,一共花了82.3元。


    我们还知道他买的啤酒比饮料的数量少,请你计算他买了几罐啤酒。


    注意:答案是一个整数。请通过浏览器提交答案。


    不要书写任何多余的内容(例如:写了饮料的数量,添加说明文字等)。


一开始用直接用题目中的带有小数点的数据运行不出来,上下乘以10以后再计算就出来了,所以说,在蓝桥杯比赛中对于这种只需要填出最终结果的小题,能用整形就用整形,避免浮点型的数以防出错。

#include<stdio.h>int main(){    for(int i=0; i<=823/23; i++)        for(int j=i+1; j<=(823-23*i)/19; j++)            if(23*i+19*j==823)                printf("%d\n",i);    return 0;}

运行结果:11


2.标题:切面条


    一根高筋拉面,中间切一刀,可以得到2根面条。


    如果先对折1次,中间切一刀,可以得到3根面条。


    如果连续对折2次,中间切一刀,可以得到5根面条。


    那么,连续对折10次,中间切一刀,会得到多少面条呢?


答案是个整数,请通过浏览器提交答案。不要填写任何多余的内容。


自己模拟剪几下,找出规律。

#include<stdio.h>int main(){    int ans=2;    for(int i=1; i<=10; i++)        ans=ans*2-1;    printf("%d\n",ans);    return 0;}

运行结果:1025



3.标题:李白打酒


    话说大诗人李白,一生好饮。幸好他从不开车。


    一天,他提着酒壶,从家里出来,酒壶中有酒2斗。他边走边唱:


    无事街上走,提壶去打酒。
    逢店加一倍,遇花喝一斗。


    这一路上,他一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了。 


    请你计算李白遇到店和花的次序,可以把遇店记为a,遇花记为b。则:babaabbabbabbbb 就是合理的次序。像这样的答案一共有多少呢?请你计算出所有可能方案的个数(包含题目给出的)。


    注意:通过浏览器提交答案。答案是个整数。不要书写任何多余的内容。


DFS,注意判断条件,以及搜索方法。

#include<stdio.h>int ans=0;char s[15];void dfs(int a,int b,int jiu,int sum){    if(!jiu&&!a&&!b&&s[14]=='b')//尤其注意这里的条件设置:酒喝光了,遇到了5个店,10朵花,最后遇到的是花。    {        ans++;        return ;    }    if(a>0)    {        s[sum]='a';        dfs(a-1,b,jiu*2,sum+1);    }    if(b>0&&jiu>0)    {        s[sum]='b';        dfs(a,b-1,jiu-1,sum+1);    }}int main(){    int jiu=2;    dfs(5,10,jiu,0);    printf("%d\n",ans);    return 0;}


运行结果:14



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


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




//计算个位 
int ge_wei(int a)
{
if(a % 2 == 0)
return (a * 2) % 10;
else
return (a * 2 + 5) % 10;
}


//计算进位 
int jin_wei(char* p)
{
char* level[] = {
"142857",
"285714",
"428571",
"571428",
"714285",
"857142"
};

char buf[7];
buf[6] = '\0';
strncpy(buf,p,6);

int i;
for(i=5; i>=0; i--){
int r = strcmp(level[i], buf);
if(r<0) return i+1;
while(r==0){
p += 6;
strncpy(buf,p,6);
r = strcmp(level[i], buf);
if(r<0) return i+1;
______________________________;  //填空
}
}

return 0;
}


//多位数乘以7
void f(char* s) 
{
int head = jin_wei(s);
if(head > 0) printf("%d", head);

char* p = s;
while(*p){
int a = (*p-'0');
int x = (ge_wei(a) + jin_wei(p+1)) % 10;
printf("%d",x);
p++;
}

printf("\n");
}


int main()
{
f("428571428571");
f("34553834937543");
return 0;
}




注意:通过浏览器提交答案。只填写缺少的内容,不要填写任何多余的内容(例如:说明性文字)

答案:if(r>0) return i;



5.标题:打印图形


    小明在X星球的城堡中发现了如下图形和文字:
rank=3
   * 
  * * 
 *   *  
* * * *


rank=5
               *                                                      
              * *                                                     
             *   *                                                    
            * * * *                                                   
           *       *                                                  
          * *     * *                                                 
         *   *   *   *                                                
        * * * * * * * *                                               
       *               *                                              
      * *             * *                                             
     *   *           *   *                                            
    * * * *         * * * *                                           
   *       *       *       *  
  * *     * *     * *     * *  
 *   *   *   *   *   *   *   * 
* * * * * * * * * * * * * * * *  


ran=6
                               *                                      
                              * *                                     
                             *   *                                    
                            * * * *                                   
                           *       *                                  
                          * *     * *                                 
                         *   *   *   *                                
                        * * * * * * * *                               
                       *               *                              
                      * *             * *                             
                     *   *           *   *                            
                    * * * *         * * * *                           
                   *       *       *       *                          
                  * *     * *     * *     * *                         
                 *   *   *   *   *   *   *   *                        
                * * * * * * * * * * * * * * * *                       
               *                               *                      
              * *                             * *                     
             *   *                           *   *                    
            * * * *                         * * * *                   
           *       *                       *       *                  
          * *     * *                     * *     * *                 
         *   *   *   *                   *   *   *   *                
        * * * * * * * *                 * * * * * * * *               
       *               *               *               *              
      * *             * *             * *             * *             
     *   *           *   *           *   *           *   *            
    * * * *         * * * *         * * * *         * * * *           
   *       *       *       *       *       *       *       *          
  * *     * *     * *     * *     * *     * *     * *     * *         
 *   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *        
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *       
                                                                      


    小明开动脑筋,编写了如下的程序,实现该图形的打印。


#define N 70


void f(char a[][N], int rank, int row, int col)
{
if(rank==1){
a[row][col] = '*';
return;
}

int w = 1;
int i;
for(i=0; i<rank-1; i++) w *= 2;

____________________________________________;
f(a, rank-1, row+w/2, col);
f(a, rank-1, row+w/2, col+w);
}


int main()
{
char a[N][N];
int i,j;
for(i=0;i<N;i++)
for(j=0;j<N;j++) a[i][j] = ' ';

f(a,6,0,0);

for(i=0; i<N; i++){
for(j=0; j<N; j++) printf("%c",a[i][j]);
printf("\n");
}

return 0;
}




    请仔细分析程序逻辑,填写缺失代码部分。


首先观察一下空格周围的式子特征,初步判定也是类似f(a, rank-1, row+w/2, col);f(a, rank-1, row+w/2, col+w);这样的式子。根据递归的规律,在f()里前两个一定是a和rank-1,后面两个基本就是靠试了,然后运行程序直到得出正确的图形。


答案:    f(a,rank-1,row, col + w/2) ;



6.标题:奇怪的分式


    上小学的时候,小明经常自己发明新算法。一次,老师出的题目是:


    1/4 乘以 8/5 


    小明居然把分子拼接在一起,分母拼接在一起,答案是:18/45 (参见图1.png)


    老师刚想批评他,转念一想,这个答案凑巧也对啊,真是见鬼!


    对于分子、分母都是 1~9 中的一位数的情况,还有哪些算式可以这样计算呢?


    请写出所有不同算式的个数(包括题中举例的)。


    显然,交换分子分母后,例如:4/1 乘以 5/8 是满足要求的,这算做不同的算式。


    但对于分子分母相同的情况,2/2 乘以 3/3 这样的类型太多了,不在计数之列!


注意:答案是个整数(考虑对称性,肯定是偶数)。请通过浏览器提交。不要书写多余的内容。



直接暴力解题,同时注意题目中要求"对于分子分母相同的情况,不在计数之列!",因此这种情况要排除。


#include<stdio.h>int main(){    double x,y,z,k;    int ans=0;    for(x=1.0; x<=9.0; x++)        for(y=1.0; y<=9.0; y++)            for(z=1.0; z<=9.0; z++)                for(k=1.0; k<=9.0; k++)                {                    if(x==y&&z==k)                        continue;                    if((x*z)/(y*k)==(10*x+z)/(10*y+k))                        ans++;                }    printf("%d\n",ans);    return 0;}

运行结果:14



7.标题:六角填数


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


    使得每条直线上的数字之和都相同。


    图中,已经替你填好了3个数字,请你计算星号位置所代表的数字是多少?


请通过浏览器提交答案,不要填写多余的内容。



暴力解题,按照图示的变量命名来


然而有时候暴力这样简单粗暴的方法也不是次次都用得好的,比如我的第一份代码就进行了19.827s 才能得出结果

第一份代码如下:

<pre name="code" class="cpp"><pre name="code" class="cpp">#include<stdio.h>int main(){    int a1,a2,a3,a4,a5,a6,a7,a8,ans,flag=0;    for(a1=1; a1<13; a1++)    {        for(a2=1; a2<13; a2++)        {            for(a3=1; a3<13; a3++)            {                for(a4=1; a4<13; a4++)                {                    for(a5=1; a5<13; a5++)                    {                        for(a6=1; a6<13; a6++)                        {                            for(a7=1; a7<13; a7++)                            {                                for(a8=1; a8<13; a8++)                                {                                    for(ans=1; ans<13; ans++)                                    {                                        if(a1==1||a1==3||a1==8||a2==1||a2==3||a2==8||a3==1||a3==3||a3==8||a4==1||a4==3||a4==8||a5==1||a5==3||a5==8||a6==1||a6==3||a6==8||a7==1||a7==3||a7==8||a8==1||a8==3||a8==8||ans==1||ans==3||ans==8)                                            continue;                                        if(a1!=a2&&a1!=a3&&a1!=a4&&a1!=a5&&a1!=a6&&a1!=a7&&a1!=a8&&a1!=ans&&a2!=a3&&a2!=a4&&a2!=a5&&a2!=a6&&a2!=a7&&a2!=a8&&a2!=ans&&a3!=a4&&a3!=a5&&a3!=a6&&a3!=a7&&a3!=a8&&a3!=ans&&a4!=a5&&a4!=a6&&a4!=a7&&a4!=a8&&a4!=ans&&a5!=a6&&a5!=a7&&a5!=a8&&a5!=ans&&a6!=a7&&a6!=a8&&a6!=ans&&a7!=a8&&a7!=ans&&a8!=ans)                                        {                                            int t1,t2,t3,t4,t5,t6;                                            t1=1+a2+a4+a8;                                            t2=1+a1+a5+ans;                                            t3=a5+a6+a7+a8;                                            t4=8+a1+a2+a3;                                            t5=8+a6+ans+3;                                            t6=3+a3+a4+a7;                                            if(t1==t2&&t2==t3&&t3==t4&&t4==t5&&t5==t6)                                            {                                                printf("%d\n",ans);                                                flag=1;                                                break;                                            }                                        }                                    }                                    if(flag)                                        break;                                }                                if(flag)                                    break;                            }                            if(flag)                                break;                        }                        if(flag)                            break;                    }                    if(flag)                        break;                }                if(flag)                    break;            }            if(flag)                break;        }    }    return 0;}



运行结果:10


实际上,暴力也是需要技巧滴~比如第二份代码就能缩短运行时间,只花了0.889s:

#include<stdio.h>int main(){    int a1,a2,a3,a4,a5,a6,a7,a8,ans;    for(a1=1; a1<13; a1++)    {        if(a1==1||a1==8||a1==3)            continue;        for(a2=1; a2<13; a2++)        {            if(a2==1||a2==8||a2==3||a2==a1)                continue;            for(a3=1; a3<13; a3++)            {                if(a3==1||a3==8||a3==3||a3==a1||a3==a2)                    continue;                for(a4=1; a4<13; a4++)                {                    if(a4==1||a4==8||a4==3||a4==a1||a4==a2||a4==a3)                        continue;                    for(a5=1; a5<13; a5++)                    {                        if(a5==1||a5==8||a5==3||a5==a1||a5==a2||a5==a3||a5==a4)                            continue;                        for(a6=1; a6<13; a6++)                        {                            if(a6==1||a6==8||a6==3||a6==a1||a6==a2||a6==a3||a6==a4||a6==a5)                                continue;                            for(a7=1; a7<13; a7++)                            {                                if(a7==1||a7==8||a7==3||a7==a1||a7==a2||a7==a3||a7==a4||a7==a5||a7==a6)                                    continue;                                for(a8=1; a8<13; a8++)                                {                                    if(a8==1||a8==8||a8==3||a8==a1||a8==a2||a8==a3||a8==a4||a8==a5||a8==a6||a8==a7)                                        continue;                                    for(ans=1; ans<13; ans++)                                    {                                        if(ans==1||ans==8||ans==3||ans==a1||ans==a2||ans==a3||ans==a4||ans==a5||ans==a6||ans==a7||ans==a8)                                            continue;                                        int t1,t2,t3,t4,t5,t6;                                        t1=1+a2+a4+a8;                                        t2=1+a1+a5+ans;                                        t3=a5+a6+a7+a8;                                        t4=8+a1+a2+a3;                                        t5=8+a6+ans+3;                                        t6=3+a3+a4+a7;                                        if(t1==t2&&t2==t3&&t3==t4&&t4==t5&&t5==t6)                                            printf("%d\n",ans);                                    }                                }                            }                        }                    }                }            }        }    }    return 0;}

运行结果:10


第二份代码的好处在于减少判断量,比如在判断9个变量互不相等的时候不必再有8!个不等式需要判断,只要保证当前for循环中的变量与之前的数不等即可。在判断六条边数字和相等时,不用写出5!个等式来判断,只需相邻两个和相等即可。

当然,暴力还是太麻烦了,运用DFS搜索算法方便快捷。第三份代码如下:

<span style="font-size:14px;">#include <cstdio>#include<string.h>int num[9]= {2,4,5,6,7,9,10,11,12};//还剩下这九个数int vis[9];int a[10];bool judge()//判断是否满足六边相等的条件{    int t1,t2,t3,t4,t5,t6;    t1=1+a[2]+a[4]+a[8];    t2=1+a[1]+a[5]+a[9];    t3=a[5]+a[6]+a[7]+a[8];    t4=8+a[1]+a[2]+a[3];    t5=8+a[6]+a[9]+3;    t6=3+a[3]+a[4]+a[7];    if(t1==t2&&t2==t3&&t3==t4&&t4==t5&&t5==t6)    {        printf("%d\n",a[9]);        return 1;    }    return 0;}void dfs(int n){    if(n==10&&judge())//搜索成功的条件是九个变量均拥有了互不相同的值,且满足六条边和相等的条件        return ;    for(int i=0; i<9; i++)        if(!vis[i])//如果num[i]还没有被赋给哪个变量过        {            a[n]=num[i];//就赋给a[n]            vis[i]=1;//标记为"已用"            dfs(n+1);//继续搜索下一个数            vis[i]=0;//标记清零,以便搜索失败后再做尝试        }}int main(){    memset(vis,0,sizeof(vis));//标记数组清零    dfs(1);//从a[1]开始搜索    return 0;}</span><span style="color: rgb(255, 0, 0); font-size: 18px;"></span>

运行结果:10


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>, 不能通过工程设置而省略常用头文件。


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



  这个题乍一看脑袋里好像很乱,其实理清头绪后再敲出来就很容易了。首先一定要记住蚂蚁都具有相同的速度,所以他们的相对位置不会变!
  我们可以从第一只那只感冒的蚂蚁入手,实际上,如果第一只蚂蚁向右爬,则它出发的位置右边的蚂蚁中向左爬且离第一只蚂蚁最近的那只会被传染,然后双方会掉头爬行,接下来,第一只蚂蚁左边的蚂蚁中向右爬行且离第一只蚂蚁最近的那只会被传染,双方再掉头。而对于一开始第一只被传染的那只蚂蚁来说,它会传染给他右边向左爬且最近的蚂蚁……
  所以,将问题简化,实际上就是向右爬的第一只感冒蚂蚁会先传染它右边所有向左爬的蚂蚁,掉头向左爬时会传染给左边所有向右爬的蚂蚁。
  同理,若第一只蚂蚁开始时是向左爬,被传染的蚂蚁=左边所有向右爬的蚂蚁+右边所有向左爬的蚂蚁。
  注意这种思想需要有个第一只感冒的蚂蚁是否会掉头的判断,因为第一只蚂蚁向左(或右)爬的时候,若不会遇到一只迎面而来的蚂蚁使它掉头的话,则即使右边有向左爬的蚂蚁,也不会被其传染。

#include<stdio.h>  #include<string.h>  struct Node  {      int pos,dir;  } Node[55];  int main()  {      int n,ans=1;      scanf("%d",&n);      memset(Node,0,sizeof(Node));      for(int i=0; i<n; i++)      {          scanf("%d",&Node[i].pos);          if(Node[i].pos>0)          {              Node[i].dir=1;          }          else          {              Node[i].dir=-1;              Node[i].pos*=-1;//注意正负仅仅表示方向,位置是其绝对值          }      }      int turn=0;//考虑到第一只感冒的蚂蚁可能不会掉头的情况,设置标记turn,初始化为0      if(Node[0].dir==1)      {          for(int i=1; i<n; i++)          {              if((Node[i].pos>Node[0].pos)&&(Node[i].dir==-1))              {                  turn=1;//第一只感冒的蚂蚁遇到迎面而来的蚂蚁,它将掉头,将turn标记为1                  ans++;              }          }          for(int i=1; i<n; i++)          {              if((Node[i].pos<Node[0].pos)&&(Node[i].dir==1)&&turn)//只有第一只蚂蚁掉头了,才会与另一方向前进的蚂蚁出现碰头的情形,因此注意加上turn是否为1的判断                  ans++;          }      }      else      {          for(int i=1; i<n; i++)          {              if((Node[i].pos<Node[0].pos)&&(Node[i].dir==1))              {                  turn=1;                  ans++;              }          }          for(int i=1; i<n; i++)          {              if((Node[i].pos>Node[0].pos)&&(Node[i].dir==-1)&&turn)                  ans++;          }      }      printf("%d\n",ans);      return 0;  }  





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>, 不能通过工程设置而省略常用头文件。


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


DFS搜索。


#include<stdio.h>long long ans;int n,m,k;int a[55][55];const int INF=0x3f3f3f3f;void dfs(int x,int y,int pre,int max){    if(pre>k)        return ;    if(x==n-1&&y==m-1)    {        if(pre==k||(pre==k-1&&max<a[x][y]))//走到终点时刚好拿到了K件礼物或者拿到了k-1件礼物,在该点的礼物的价值又大于之前拿到的最大价值。此时方案数加一。            ans++;        return ;    }    if(x<n-1)//向下走    {        if(a[x][y]>max)            dfs(x+1,y,pre+1,a[x][y]);        dfs(x+1,y,pre,max);    }    if(y<m-1)//向右走    {        if(a[x][y]>max)            dfs(x,y+1,pre+1,a[x][y]);        dfs(x,y+1,pre,max);    }}int main(){    while(~scanf("%d%d%d",&n,&m,&k))    {        for(int i=0; i<n; i++)            for(int j=0; j<m; j++)                scanf("%d",&a[i][j]);        ans=0;        dfs(0,0,0,-INF);        printf("%lld\n",ans%1000000007);    }    return 0;}<span style="color:#ff0000;"></span>

上面的代码是普通的DFS搜索。


记忆化搜索:

<span style="font-size:14px;">#include<stdio.h>  #include<string.h>  int n,m,k;  int a[55][55][15][15];  int map[55][55];  int dfs(int x,int y,int pre,int max)  {      if(a[x][y][pre][max+1]>=0)          return a[x][y][pre][max+1];      int sum=0;      if(x==n-1&&y==m-1)      {          if(pre==k||(pre==k-1&&max<map[x][y]))          {              sum++;              sum%=1000000007;          }          a[x][y][pre][max+1]=sum;          return a[x][y][pre][max+1];      }      if(x<n-1)      {          if(map[x][y]>max)              sum+=dfs(x+1,y,pre+1,map[x][y]);          sum+=dfs(x+1,y,pre,max);          sum%=1000000007;      }      if(y<m-1)      {          if(map[x][y]>max)              sum+=dfs(x,y+1,pre+1,map[x][y]);          sum+=dfs(x,y+1,pre,max);          sum%=1000000007;      }      a[x][y][pre][max+1]=sum%1000000007;      return a[x][y][pre][max+1];  }  int main()  {      while(~scanf("%d%d%d",&n,&m,&k))      {          memset(a,-1,sizeof(a));          for(int i=0; i<n; i++)              for(int j=0; j<m; j++)                  scanf("%d",&map[i][j]);          dfs(0,0,0,-1);          printf("%lld\n",a[0][0][0][0]%1000000007);      }      return 0;  }  </span>





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>, 不能通过工程设置而省略常用头文件。


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


树状数组和归并排序的应用,还不会……

3 0
原创粉丝点击