zoukankan      html  css  js  c++  java
  • 8月21日小练

    网站:   8月21日小练

    A    HDU2554    N对数的排列问题

    题解来自:http://blog.csdn.net/ilovexiaohao/article/details/8717846  

    这题可以这样来抽象:

    n对数,大小为1、2、3、...、n。现要求两个1之间有1个数,两个2之间有2个数,以此类推,两个n之间有n个数。

    并且,数的次序可以随意的。

    准备知识:

    ①n对数,共2*n个数。所以要有2*n个位置来放置这2*n个数。②sum()表示求和运算。

    正式解决:

    ①设k(k=1,2,..,n)放置的第一个位置为ak,第二个位置为bk。显然有bk-ak=k+1(假定下一个位置在上一个位置之前)。

    那么会有sum(bk-ak)=2+3+4+...+(n+1)=(1+2+3+...+n)+(1+1+...+1)=n*(n+1)/2+n。

    ②又因为要有2*n个位置来放置这2*n个数。则sum(ak+bk)=1+2+3+...+2*n=(1+2*n)*(2*n)/2=(1+2*n)*n。

    ③sum(ak+bk)=sum(ak+ak+k+1)=sum(2*ak+bk-ak)=2*sum(ak)+sum(bk-ak)=2*sum(ak)+n*(n+1)/2+n。

    ④比较②③可得:(1+2*n)*n=2*sum(ak)+n*(n+1)/2+n。可得sum(ak)=n*(3*n-1)/4。

    ⑤就像前面已经说过的一样,ak表示数k第一次出现的位置。ak不易确定。当可以肯定的是sum(ak)一定为正整数。

    那么就会有n=4*p或者3*n-1=4*p(p为正整数)。

    代码:    31ms

     1 #include <stdio.h>
     2 #include <iostream>
     3 using namespace std;
     4 int main()
     5 {
     6     int n;
     7     while(~scanf("%d",&n)&&n)
     8     {
     9         if(n%4==0 || (3*n-1)%4==0)
    10             printf("Y
    ");
    11         else
    12             printf("N
    ");
    13     }
    14     return 0;
    15 }

    B     Big Number    HDU 1018

    a的长度=log10(a)+1;

    a=1*2*3*4*......*n;

    log10(1*2*3*4......*n)=log10(1)+log10(2)+log10(3)+.....+log10(n);

    代码:   968ms

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <math.h>
     4 using namespace std;
     5 int main()
     6 {
     7     int n,i,T;
     8     double sum;
     9     scanf("%d",&T);
    10     while(T--)
    11     {
    12         scanf("%d",&n);
    13         sum=0;
    14         for(i=1;i<=n;i++)
    15           sum=sum+log10((double)i);    //要注意i要转化为double 
    16         printf("%d
    ",(int)sum+1);   //转化为int 
    17     }
    18     return 0;
    19 }

    C     Going Home      HDU 1533     KM算法

    D     Invitation Cards     POJ 1511    最短路(spfa算法)

    E     命运     HDU 2571   要从左上角到达右下角,每个格子都有个数值,求最大的和为多少,只能向右走或者向下走,向右走有两种可能,一种是走一步,也可以走到当前坐标的倍数去。

    DP思想:每走一步,找到可能的上一步的最大值,再加上自己这个格子的值。

    代码:    46ms

     1 #include <stdio.h>
     2 #include <iostream>
     3 using namespace std;
     4 int dp[22][1005];
     5 int main()
     6 {
     7     int T,m,n,i,j,maxx,k;
     8     scanf("%d",&T);
     9     while(T--)
    10     {
    11         scanf("%d%d",&m,&n);
    12         for(i=1;i<=m;i++)
    13             for(j=1;j<=n;j++)
    14             {
    15                 scanf("%d",&dp[i][j]);
    16                 maxx=-9999990;    //初始化
    17                 for(k=1;k<j;k++)
    18                     if(j%k==0)    //倍数的最大值
    19                         maxx=max(maxx,dp[i][k]);
    20                 if(j!=1)   //往上找
    21                     maxx=max(maxx,dp[i][j-1]);
    22                 if(i!=1)   
    23                     maxx=max(maxx,dp[i-1][j]);
    24                 if(i==1&&j==1)
    25                     maxx=0;
    26                 dp[i][j]+=maxx;
    27             }
    28         printf("%d
    ",dp[m][n]);    //最后一个格子的值
    29     }
    30     return 0;
    31 }
  • 相关阅读:
    pytest文档55-plugins插件开发
    pytest文档54-Hooks函数terminal打印测试结果(pytest_report_teststatus)
    Linux内存占用过高排查过程
    系统日志:/var/log/messages
    win10 安装oracle 11gR2_database(内附下载地址)
    CentOS 7 下 Docker 的离线安装方法
    docker 常用命令
    【docker】如何将服务器加入集群,成为子节点
    Docker管理面板系列——Portainer
    基于Docker的Consul服务发现集群搭建
  • 原文地址:https://www.cnblogs.com/riddle/p/3274385.html
Copyright © 2011-2022 走看看