zoukankan      html  css  js  c++  java
  • 7.20试机测 T3 阶乘之和 暴力AC题解

    7.20试机测  T3 阶乘之和 暴力AC题解

    题外话:此乃本蒟蒻发表的第一篇题解,大家多多关照,支持一下,谢谢


    题面

    3、阶乘之和(sum.pas/in/out)

    问题描述: 给定一个非负整数 n,请你判断 n 是否可以由一些非负整数的阶乘相加得到。

    问题输入: 有若干组数据。每行一个整数 n,保证 n<1000000。 以负数结束输入。

    问题输出: 对于每组数据输出一行,若可以则输出‘YES’,否则输出‘NO’。

    输入样例: 9 -1

    样例输出: YES


    分析

    这个题嘛

    大概了解了一下题意,就是给出n,判断n能不能被几个数的阶乘加起来。(虽然题目没有说清楚数字能不能重复,但是我们知道1的阶乘是1,如果数字可以重复的话,那么任何n都是YES了,所以我推测所选数字不能重复)


     

    题目让输入多组数据,我们先针对一个数据进行操作,在结尾再弄关于输入多组数据的问题…………

    下面算出一些较小数的阶乘(千万不要忘记0)(这一步可以在Excel完成,用FACT函数)

    看到数据范围, n<1000000,可以了解到所选的数字应该在0~9里。

    那么,n的最大值就确定了,即0~9的阶乘之和(1+1+2+6+24+...+40320+362880=409114)

     

    也就是说,只要n的值超过了409114,那么这个n就不符合条件,可以提前判断一部分n是不是NO。

    还有,0的阶乘是1,那么如果n的值为0,就没有非负整数满足n,也是直接NO。

    if(n>409114 || n==0)
        cout<<"NO"<<endl;

     


     下面怎么办呢,暴力?!

    在这里,我还没有学一些什么神奇01背包,二进制什么玩意……

    我就简简单单地用几个for循环来搜出所有情况吧。

     

    先开一个数组(第一个开0是防止有??的情况   其实第一个完全可以不开0,不开0还节省了时间)

    long long x[11]= {0,1,1,2,6,24,120,720,5040,40320,362880};

     

    我们知道,题目给定一个n,这个n可能由上面数组中的1个数相加得到,也可能是2个,也可能是多个……

    (比如n=4时,n是1+1+2,由数组中的3个数相加得到;n=25时,则为1+24,由数组中的2个数相加得到)

     

    那么,我们先假设n由上面选1个数得到,则可以

    for(int a=0; a<11; ++a)
        if(x[a]==n)
        {
           cout<<"YES"<<endl;
        }

     

    如果一个数不行,那就看看2个数加起来能不能得到n

    这里防止有判重的情况,就让b=a+1,还节省了时间。

    for(int a=0; a<11; ++a)
        for(int b=a+1; b<11; ++b)
            if(x[a]+x[b]==n)
            {
                cout<<"YES"<<endl;
            }

     

    下面以此类推……直到10个数的时候

    for(int a=0; a<11; ++a)
    for(int b=a+1; b<11; ++b) for(int c=b+1; c<11; ++c) for(int d=c+1; d<11; ++d) for(int e=d+1; e<11; ++e) for(int f=e+1; f<11; ++f) for(int g=f+1; g<11; ++g) for(int h=g+1; h<11; ++h) for(int i=h+1; i<11; ++i) for(int j=i+1; j<11; ++j) if(x[a]+x[b]+x[c]+x[d]+x[e]+x[f]+x[g]+x[h]+x[i]+x[j]==n) { cout<<"YES"<<endl; }

     

    这样就行了?此处忽略了一个地方,假设n由5个数相加就能得到,那么下面的6次,7次循环再执行岂不是浪费掉了时间嘛。

    所以,我们开一个布尔变量,用来判断n是不是已经被配对

    bool yes=false;

     


     

    好了,现在我们可以研究输入多组数据的问题了,因为不研究这个,布尔变量就没法展现它的作用。

    题意说输入负数的时候结束程序(千万不要被样例迷惑了,不一定是-1结束程序)

    那么,可以用while循环输入数据。

    每输入一个n,就对n执行一次下面的操作。 直到n<0时,return 0 结束程序。

    <0

    int main()
    {
        while(scanf("%d",n) && n>=0)
        {
            yes=false;
            //此处往下写程序,每次当n配对时,把布尔变量变成true。
        }
      return 0; }

     

    当n被配对时,变量yes的值为true。我们可以在程序中疯狂检测 yes的值,只要是true就立即让它输出“YES”,然后扔掉此时的n,再对下一个数字n进行操作。

     

    具体操作如下(拿n由4个数相加得到 举例):

            for(int a=0; a<11; ++a)
            {
                for(int b=a+1; b<11; ++b)
                {
                    for(int c=b+1; c<11; ++c)
                    {
                        for(int d=c+1; d<11; ++d)
                            if(x[a]+x[b]+x[c]+x[d]==n)
                            {
                                cout<<"YES"<<endl;
                                yes=true; //只要n被配对成功,就把布尔设为true
                                break;
                            }
                        if(yes==true) break;   //让被配对成功的n 一路顺风,跳出循环
                    }
                    if(yes==true) break;  
                }
                if(yes==true) break;
            }
    
         if(yes==true) continue;  //此时的 continue 与 while 读入操作在同一层。这样就可以读入下一个n了

     

    这样看起来好像有点麻烦,但是我觉得理解起来不难吧qwq.

     

    最后当10次循环都走一遍,结果n没有找到合适的数字,就在末尾输出“NO”.

     


    AC代码:

      1 /*---------------------------------
      2  *Title number:  7.20 试机测 T3 阶乘之和 
      3  *Creation date: 2020-07-20 afternoon
      4  *By: EdisonBa
      5  *-------------------------------*/
      6 #include<iostream>
      7 #include<cstdio>
      8 #include<cmath>
      9 #include<cstdlib>
     10 #include<cstring>
     11 #include<algorithm>
     12 using namespace std;
     13 
     14 long long x[11]= {0,1,1,2,6,24,120,720,5040,40320,362880};
     15 long long n;
     16 bool yes=false;
     17 
     18 int main()
     19 {
     20     while(cin>>n && n>=0)
     21     {
     22         yes=false;  //每一次对n操作都要重置一下布尔变量 yes 
     23         
    24 //下面判一下最大值和0 25
    26 if(n>409114 || n==0) 27 { 28 cout<<"NO"<<endl; 29 continue; 30 } 31
    32 //下面进行第 1 次循环 33
    34 for(int a=0; a<11; ++a) 35 if(x[a]==n) 36 { 37 cout<<"YES"<<endl; 38 yes=true; 39 break; 40 } 41 42 if(yes==true) continue; 43
    44 //下面进行第 2 次循环 45
    46 for(int a=0; a<11; ++a) 47 { 48 for(int b=a+1; b<11; ++b) 49 50 if(x[a]+x[b]==n) 51 { 52 cout<<"YES"<<endl; 53 yes=true; 54 break; 55 } 56 if(yes==true) break; 57 } 58 59 if(yes==true) continue; 60
    61 //下面进行第 3 次循环 62
    63 for(int a=0; a<11; ++a) 64 { 65 for(int b=a+1; b<11; ++b) 66 { 67 for(int c=b+1; c<11; ++c) 68 69 if(x[a]+x[b]+x[c]==n) 70 { 71 cout<<"YES"<<endl; 72 yes=true; 73 break; 74 } 75 if(yes==true) break; 76 } 77 if(yes==true) break; 78 } 79 80 if(yes==true) continue; 81
    82 //下面进行第 4 次循环 83
    84 for(int a=0; a<11; ++a) 85 { 86 for(int b=a+1; b<11; ++b) 87 { 88 for(int c=b+1; c<11; ++c) 89 { 90 for(int d=c+1; d<11; ++d) 91 if(x[a]+x[b]+x[c]+x[d]==n) 92 { 93 cout<<"YES"<<endl; 94 yes=true; 95 break; 96 } 97 if(yes==true) break; 98 } 99 if(yes==true) break; 100 } 101 if(yes==true) break; 102 } 103 104 if(yes==true) continue; 105
    106 //下面进行第 5 次循环 107
    108 for(int a=0; a<11; ++a) 109 { 110 for(int b=a+1; b<11; ++b) 111 { 112 for(int c=b+1; c<11; ++c) 113 { 114 for(int d=c+1; d<11; ++d) 115 { 116 for(int e=d+1; e<11; ++e) 117 if(x[a]+x[b]+x[c]+x[d]+x[e]==n) 118 { 119 cout<<"YES"<<endl; 120 yes=true; 121 break; 122 } 123 if(yes==true) break; 124 } 125 if(yes==true) break; 126 } 127 if(yes==true) break; 128 } 129 if(yes==true) break; 130 } 131 132 133 if(yes==true) continue; 134
    135 //下面进行第 6 次循环 136
    137 for(int a=0; a<11; ++a) 138 { 139 for(int b=a+1; b<11; ++b) 140 { 141 for(int c=b+1; c<11; ++c) 142 { 143 for(int d=c+1; d<11; ++d) 144 { 145 for(int e=d+1; e<11; ++e) 146 { 147 for(int f=e+1; f<11; ++f) 148 if(x[a]+x[b]+x[c]+x[d]+x[e]+x[f]==n) 149 { 150 cout<<"YES"<<endl; 151 yes=true; 152 break; 153 } 154 if(yes==true) break; 155 } 156 if(yes==true) break; 157 } 158 if(yes==true) break; 159 } 160 if(yes==true) break; 161 } 162 if(yes==true) break; 163 } 164 165 if(yes==true) continue; 166
    167 //下面进行第 7 次循环 168
    169 for(int a=0; a<11; ++a) 170 { 171 for(int b=a+1; b<11; ++b) 172 { 173 for(int c=b+1; c<11; ++c) 174 { 175 for(int d=c+1; d<11; ++d) 176 { 177 for(int e=d+1; e<11; ++e) 178 { 179 for(int f=e+1; f<11; ++f) 180 { 181 for(int g=f+1; g<11; ++g) 182 if(x[a]+x[b]+x[c]+x[d]+x[e]+x[f]+x[g]==n) 183 { 184 cout<<"YES"<<endl; 185 yes=true; 186 break; 187 } 188 if(yes==true) break; 189 } 190 if(yes==true) break; 191 } 192 if(yes==true) break; 193 } 194 if(yes==true) break; 195 } 196 if(yes==true) break; 197 } 198 if(yes==true) break; 199 } 200 201 if(yes==true) continue; 202
    203 //下面进行第 8 次循环 204
    205 for(int a=0; a<11; ++a) 206 { 207 for(int b=a+1; b<11; ++b) 208 { 209 for(int c=b+1; c<11; ++c) 210 { 211 for(int d=c+1; d<11; ++d) 212 { 213 for(int e=d+1; e<11; ++e) 214 { 215 for(int f=e+1; f<11; ++f) 216 { 217 for(int g=f+1; g<11; ++g) 218 { 219 for(int h=g+1; h<11; ++h) 220 if(x[a]+x[b]+x[c]+x[d]+x[e]+x[f]+x[g]+x[h]==n) 221 { 222 cout<<"YES"<<endl; 223 yes=true; 224 break; 225 } 226 if(yes==true) break; 227 } 228 if(yes==true) break; 229 } 230 if(yes==true) break; 231 } 232 if(yes==true) break; 233 } 234 if(yes==true) break; 235 } 236 if(yes==true) break; 237 } 238 if(yes==true) break; 239 } 240 241 if(yes==true) continue; 242
    243 //下面进行第 9 次循环 244
    245 for(int a=0; a<11; ++a) 246 { 247 for(int b=a+1; b<11; ++b) 248 { 249 for(int c=b+1; c<11; ++c) 250 { 251 for(int d=c+1; d<11; ++d) 252 { 253 for(int e=d+1; e<11; ++e) 254 { 255 for(int f=e+1; f<11; ++f) 256 { 257 for(int g=f+1; g<11; ++g) 258 { 259 for(int h=g+1; h<11; ++h) 260 { 261 for(int i=h+1; i<11; ++i) 262 263 if(x[a]+x[b]+x[c]+x[d]+x[e]+x[f]+x[g]+x[h]+x[i]==n) 264 { 265 cout<<"YES"<<endl; 266 yes=true; 267 break; 268 } 269 if(yes==true) break; 270 } 271 if(yes==true) break; 272 } 273 if(yes==true) break; 274 } 275 if(yes==true) break; 276 } 277 if(yes==true) break; 278 } 279 if(yes==true) break; 280 } 281 if(yes==true) break; 282 } 283 if(yes==true) break; 284 } 285 286 if(yes==true) continue; 287
    288 //下面进行第 10 次循环 289
    290 for(int a=0; a<11; ++a) 291 { 292 for(int b=a+1; b<11; ++b) 293 { 294 for(int c=b+1; c<11; ++c) 295 { 296 for(int d=c+1; d<11; ++d) 297 { 298 for(int e=d+1; e<11; ++e) 299 { 300 for(int f=e+1; f<11; ++f) 301 { 302 for(int g=f+1; g<11; ++g) 303 { 304 for(int h=g+1; h<11; ++h) 305 { 306 for(int i=h+1; i<11; ++i) 307 { 308 for(int j=i+1; j<11; ++j) 309 if(x[a]+x[b]+x[c]+x[d]+x[e]+x[f]+x[g]+x[h]+x[i]+x[j]==n) 310 { 311 cout<<"YES"<<endl; 312 yes=true; 313 break; 314 } 315 if(yes==true) break; 316 } 317 if(yes==true) break; 318 } 319 if(yes==true) break; 320 } 321 if(yes==true) break; 322 } 323 if(yes==true) break; 324 } 325 if(yes==true) break; 326 } 327 if(yes==true) break; 328 } 329 if(yes==true) break; 330 } 331 if(yes==true) break; 332 } 333 334 if(yes==true) continue; 335
    336 // 10次循环完毕,若n没有合适的数字,输出"NO" 337 338 cout<<"NO"<<endl; 339 340 } 341 342 return 0; 343 }

     

     https://www.luogu.com.cn/record/35414283

     

     

    (此代码对于 第10个毒瘤点来说 能过就是奇迹)


     

    这份代码,显然不是最优解(第10个测试点的时间快要爆了),如果把x数组里的0删去,可能时间会稍微短那么几毫秒。

    但是这个理解起来很容易,只要有充足的时间就能写出来(大概半个多小时)。

    我觉得这个代码的关键就是在每次大循环中,下层的for的变量值是上层的变量值+1(无法表述啊这)

    -----------------------------------------------------------------------------------------------------------------------------------------------

    看图:

     

     -----------------------------------------------------------------------------------------------------------------------------------------------

    这样节省了大部分时间,也防止出现了判重的情况,使得多次大循环顺利过测试点。


     感谢您观看此题解。

    这是本蒟蒻发表的第一篇题解,岂不妙哉?!

    希望在接下来的时间里,大家共同成长,共同进步,多多交流,共创辉煌!

     

    EdisonBa

    2020/7/20

     

  • 相关阅读:
    SQL Server 2016 Community Technology Preview 3.3
    orchard project 本地化
    Visual Studio Code
    Solidworks如何制作动画2
    Solidworks如何运行Toolbox
    Solidworks如何显示装饰螺纹线
    Solidworks如何将参考平面的图形投影到某曲面上
    Solidworks如何绘制装饰螺纹线
    Solidworks如何绘制文字
    SolidWorks如何绘制抽壳零件
  • 原文地址:https://www.cnblogs.com/EdisonBa/p/13345998.html
Copyright © 2011-2022 走看看