zoukankan      html  css  js  c++  java
  • hiho_offer收割18_题解报告_差第四题

    I.求逆元
    欧几里得方法

    II.模拟
    细心+耐心

    *本人感悟:
    自己的错误在于:
    对于这道模拟题没有耐心静下来一字一字看题,一行一行调错,一步一步调试,我要引以为戒。


    III.dp
    f[i][j][k]=max(f[i-1][j][k],min(f[i-1][t][k-1])+value[i][k])
    t=0,1,…,801

    i为第i个曲子(长度为3)
    j为至今已进行j次的和弦改变(j<=c(c为允许和弦改变的最多次数))
    k为第k种和弦的方法
    value[i][k]为用对第i个曲子用第k个和弦的不和谐值

    本人想到的进一步优化(本题不用):
    1.求出全程不能变音的最小值

    2.对于某个变音方法,如果其值已经大于最小值,则该方法不能继续进行下去

    具体操作:
    把对应第1~i个曲子可以实现的和弦存放到数组,生成第1~i+1个曲子可以实现的和弦

    时间复杂度:
    i<=1000
    j<=20
    k<=802

    对于每个i,k,求出一次min(f[i-1][t][k-1])即可

    O(nk*802)
    1000*20*802=16040000
    可在一秒内解决

    *另:注意数组维数的范围
    如发现错误,可在各个位置设置“输出一个数”,看哪里不正常,那么就是哪里出错了

    *测试数据:
    如n=1000,k=20
    其它全为0
    判断是否数组开的正确

    IV.
    实际上,没多少斤两就不要想第四题了,看看题目和测试数据就知道是不想让你用简单方法拿点分了

    反正不会做
    下面是想法:


    不同的分图没有边相连,不互相影响,可分开考虑

    以k个点为标准点,分别考虑这k个点是否发生故障,除去??? 不行,2^k 太大了

    有第i个点和有第j点,


    当某边在/不在时

    当某点在/不在时


    当n很大时

    当m很大时

    极限数据:
    100000个点,编号为前400的点,每个点之间都有一个边相连;剩下的点都仅与编号为1的点相连

     1.

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 
     4 long s,t;
     5 
     6 void gcd(long x,long y)
     7 {
     8     if (y==0)
     9     {
    10         s=1;
    11         t=0;
    12         return;
    13     }
    14     long r,q;
    15     r=x/y;
    16     gcd(y,x%y);
    17     q=s;
    18     s=t;
    19     t=q-r*t;
    20 }
    21 
    22 int main()
    23 {
    24     long a,b,p;
    25     scanf("%ld%ld%ld",&a,&b,&p);
    26     b=b%p;
    27     gcd(p,b);
    28     t=t%p+p;
    29     printf("%ld
    ",a*t%p);
    30     return 0;
    31 }

    2.

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <stdbool.h>
      4 #include <string.h>
      5 
      6 struct node
      7 {
      8     long f[4];
      9     long a[3];
     10 }pai[10];
     11 
     12 long n;
     13 
     14 bool judge()
     15 {
     16     long j,k,g;
     17     //1
     18     for (j=0;j<4;j++)
     19     {
     20         g=0;
     21         for (k=0;k<n;k++)
     22             g+=pai[k].f[j];
     23         if (g==5)
     24             return true;
     25     }
     26     //2
     27     for (j=0;j<n;j++)
     28         if (pai[j].a[0]>0)
     29             break;
     30     if (j!=n)
     31     {
     32         for (j=0;j<n;j++)
     33             if (pai[j].f[0]+pai[j].f[1]+pai[j].f[2]+pai[j].f[3]>0)
     34                 break;
     35         if (j!=n)
     36         {
     37             for (j=0;j<n;j++)
     38                 if (pai[j].f[3]>0)
     39                     break;
     40             if (j==n)
     41                 return true;
     42         }
     43     }
     44     //3
     45     for (j=0;j<n;j++)
     46         if (pai[j].a[1]>0)
     47             break;
     48     if (j!=n)
     49     {
     50         for (j=0;j<n;j++)
     51             if (pai[j].f[0]+pai[j].f[1]+pai[j].f[2]+pai[j].f[3]>0)
     52                 break;
     53         if (j!=n)
     54         {
     55             for (j=0;j<n;j++)
     56                 if (pai[j].f[1]>0)
     57                     break;
     58             if (j==n)
     59                 return true;
     60         }
     61     }
     62     //4
     63     for (j=0;j<n;j++)
     64         if (pai[j].a[2]>0)
     65             break;
     66     if (j!=n)
     67     {
     68         for (j=0;j<n;j++)
     69             if (pai[j].f[0]+pai[j].f[1]+pai[j].f[2]+pai[j].f[3]>0)
     70                 break;
     71         if (j!=n)
     72             return true;
     73     }
     74     return false;
     75 }
     76 
     77 int main()
     78 {
     79     long c,g,t,i,j,k,sum[10],tot[10],num;
     80     char s[50];
     81     scanf("%ld%ld",&n,&c);
     82     for (i=0;i<n;i++)
     83         sum[i]=10000000;
     84     for (i=0;i<n;i++)
     85         tot[i]=0;
     86     num=0;
     87     for (i=1;i<=c;i++)
     88     {
     89         scanf("%s",s);
     90         if (strcmp(s,"Fruit")==0)
     91         {
     92             tot[num]++;
     93             sum[num]--;
     94             for (j=0;j<4;j++)
     95                 pai[num].f[j]=0;
     96             for (j=0;j<3;j++)
     97                 pai[num].a[j]=0;
     98             scanf("%ld",&g);
     99             for (j=1;j<=g;j++)
    100             {
    101                 scanf("%ld",&t);
    102                 pai[num].f[t]++;
    103             }
    104             num=(num+1)%n;
    105         }
    106         else if (strcmp(s,"Animal")==0)
    107         {
    108             tot[num]++;
    109             sum[num]--;
    110             for (j=0;j<4;j++)
    111                 pai[num].f[j]=0;
    112             for (j=0;j<3;j++)
    113                 pai[num].a[j]=0;
    114             scanf("%ld",&t);
    115             pai[num].a[t]=1;
    116             num=(num+1)%n;
    117         }
    118         else
    119         {
    120             scanf("%ld",&t);
    121             if (judge()==true)
    122             {
    123                 for (j=0;j<n;j++)
    124                     sum[t]+=tot[j];
    125                 for (j=0;j<n;j++)
    126                 {
    127                     tot[j]=0;
    128                     for (k=0;k<4;k++)
    129                         pai[j].f[k]=0;
    130                     for (k=0;k<3;k++)
    131                         pai[j].a[k]=0;
    132                 }
    133             }
    134             else
    135             {
    136                 sum[t]-=n;
    137                 for (j=0;j<n;j++)
    138                     sum[j]++;
    139             }
    140             num=t;
    141         }
    142         //printf("%ld %ld %ld
    ",sum[0],sum[1],sum[2]);
    143     }
    144     for (i=0;i<n;i++)
    145         printf("%ld
    ",sum[i]);
    146     return 0;
    147 }

    3.

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <math.h>
     4 #define maxf 10000000
     5 //max=400*3000=1200000
     6 
     7 long music[3001],value[1001][802],f[1001][21][802],ch[1001];
     8 
     9 long min(long a,long b)
    10 {
    11     if (a>b)
    12         return b;
    13     else
    14         return a;
    15 }
    16 
    17 int main()
    18 {
    19     long n,g,i,j,k,l,m,pr;
    20     scanf("%ld%ld",&n,&g);
    21     for (i=1;i<=3*n;i++)
    22         scanf("%ld",&music[i]);
    23     for (i=0;i<=400;i++)
    24     {
    25         j=i-200;
    26         l=0;
    27         m=0;
    28         for (k=1;k<=n;k++)
    29         {
    30             m++;
    31             value[m][i]=0;
    32             l++;
    33             value[m][i]+=abs(j-music[l]);
    34             l++;
    35             value[m][i]+=abs(j+4-music[l]);
    36             l++;
    37             value[m][i]+=abs(j+7-music[l]);
    38         }
    39     }
    40 
    41     for (i=401;i<=801;i++)
    42     {
    43         j=i-601;
    44         l=0;
    45         m=0;
    46         for (k=1;k<=n;k++)
    47         {
    48             m++;
    49             value[m][i]=0;
    50             l++;
    51             value[m][i]+=abs(j-music[l]);
    52             l++;
    53             value[m][i]+=abs(j+3-music[l]);
    54             l++;
    55             value[m][i]+=abs(j+7-music[l]);
    56         }
    57     }
    58 
    59     for (i=1;i<=n;i++)
    60         for (j=1;j<=g;j++)
    61             for (k=0;k<802;k++)
    62                 f[i][j][k]=maxf;
    63 
    64     for (k=0;k<802;k++)
    65         f[0][0][k]=0;
    66     for (i=1;i<=n;i++)
    67         for (k=0;k<802;k++)
    68             f[i][0][k]=f[i-1][0][k]+value[i][k];
    69 
    70     pr=maxf;
    71     //2
    72     for (i=2;i<=n;i++)
    73     {
    74         //0 <g
    75         for (j=0;j<min(i-1,g);j++)
    76         {
    77             ch[j]=maxf;
    78             for (k=0;k<802;k++)
    79                 ch[j]=min(ch[j],f[i-1][j][k]);
    80         }
    81         //1(0 不用计算)
    82         for (j=0;j<=min(i-1,g);j++)
    83         {
    84             for (k=0;k<802;k++)
    85             {
    86                 f[i][j][k]=f[i-1][j][k]+value[i][k];
    87                 if (j!=0)
    88                     f[i][j][k]=min(f[i][j][k],ch[j-1]+value[i][k]);
    89             }
    90         }
    91     }
    92 
    93     for (j=0;j<=g;j++)
    94         for (k=0;k<802;k++)
    95             pr=min(pr,f[n][j][k]);
    96 
    97     printf("%ld
    ",pr);
    98     return 0;
    99 }


    by lzu_cgb
    share & spread ideas

  • 相关阅读:
    使用JDK创建webService
    eclipse换工作空间要做的事情
    JAVA输出表格(适配中英文)
    linux下如何用GDB调试c++程序
    C++编译的四个步骤
    linux下如何设置root密码(第一次)
    chp01、Dreamweaver介绍
    服务器端程序
    1_计算机网络概述
    Oracle Java JDBC: Get Primary Key Of Inserted Record
  • 原文地址:https://www.cnblogs.com/cmyg/p/7191501.html
Copyright © 2011-2022 走看看