zoukankan      html  css  js  c++  java
  • 题解 P2089 【烤鸡】

    看到这个题一共也就pow(3,10)=59049次循环,那不就暴力了嘛!
    虽然说正解是动归和搜索
    但是搜索和暴力枚举的差距真心不大(不好好学习qwq)
    看到楼上又说到

    答案需要数据存储的问题,

    这里提供一种借助STL的queue(队列)来进行存储的方法。

    这个方法难度几乎为0,每个新手都可以学习!


    原理:队列的先入先出原则

    操作:
    队列名.push(变量名)
    将变量压入队列
    队列名.front()
    返回队列头部元素
    队列名.pop()
    弹出队列头部元素

    以下是例子:
    假设Farmer John想让你对输入的数据进行分类(ABCD类)存储,
    并且把指定的类型(A型)的数据全部按照输入的顺序输出来
    给一个数据总数,再一个个把数据给你。(假设同一类型的数据最多8个)

    输入样例:         输出样例:
    6                 21 -12 102
    A 21
    A -12
    A 102
    B 134011
    D 2147483647
    C 2147483647
    

    于是样例程序就是:

    #include <queue>
    //以上是队列必须要加上的头文件
    #include <cstdio>
    using namespace std;
    queue<int>qwq[4];
    //<你要使用的类型>随便一个合法的名字
    //队列是数据类型,可以作为数组使用!
    int main()
    {
    	int n,input;
        char ch;
        cin>>n;
        for (int i=1;i<=n;i++)
        	cin>>ch>>input;
            qwq[ch-'A'].push(input);
            //操作:将数据压入队列
        while (!qwq[0].empty())
        	cout<<qwq.front();qwq.pop();
            //操作:输出队列最先输入的第一个元素,然后弹出它
        //直到qwq[0]内没有元素
        return 0;
    }
    

    用队列的好处就是如果没有元素输入,那就没有输出,不浪费内存。
    这种情况(巨毒瘤)在我学校老师出的题里面有...
    Python 3的列表也可以用类似这个方法的方法来存储数据,但是方便许多
    假的,因为弹出头部元素其他都得跟着一块动,伤不起。


    回归正题。

    既然要减少循环次数,那么就可以使用它。

    但仍有最坏的情况(n=20)出现。

    那么最坏情况需要输出多少次呢?
    答案:8953
    太好了!尽情使用吧!管他呢!这种情况之下队列优化也没有办法!
    (Mode:c++)Code:

    #include <iostream>
    #include <cstdio>
    #include <queue>
    
    using namespace std;
    struct peiliao{//自定义类型peiliao作为队列的元素
        int a,b,c,d,e,f,g,h,i,j;
    };
    queue<peiliao>qwq;//存储容器在这里!!!!!!!
    
    int main()
    {
        int a,b,c,d,e,f,g,h,i,j,n;
        peiliao kaoji;//暂时性质的变量peiliao元素
        scanf("%d",&n);
        if (n<10||n>30)
        {//如果小于10或者是大于30,肯定做不出要求的烤鸡
        	putchar('0');return 0;
        }
        for (a=1;a<=3;a++)
            for (b=1;b<=3;b++)
                for (c=1;c<=3;c++)
                    for (d=1;d<=3;d++)
                        for (e=1;e<=3;e++)
                            for (f=1;f<=3;f++)
                                for (g=1;g<=3;g++)
                                    for (h=1;h<=3;h++)
                                        for (i=1;i<=3;i++)
                                            for (j=1;j<=3;j++)
                                                if (a+b+c+d+e+f+g+h+i+j==n)
                                                {
                                                    kaoji.a=a,kaoji.b=b,kaoji.c=c,kaoji.d=d,kaoji.e=e;
                                                    kaoji.f=f,kaoji.g=g,kaoji.h=h,kaoji.i=i,kaoji.j=j;
                                                    qwq.push(kaoji);//压入在这里!!!!!!!
                                                }
        if (qwq.empty())
        {
            putchar('0');
        }
        else
        {
            printf("%d
    ",qwq.size());
            while (!qwq.empty())
            {输出在这里!!!!!!!!
                kaoji=qwq.front();
                qwq.pop();
                cout<<kaoji.a<<' '<<kaoji.b<<' '<<kaoji.c;
                cout<<' '<<kaoji.d<<' '<<kaoji.e<<' '<<kaoji.f;
                cout<<' '<<kaoji.g<<' '<<kaoji.h<<' '<<kaoji.i;
                cout<<' '<<kaoji.j<<endl;
            }
        }
        return 0;
    }
    

    (Mode:Python 3)Code:
    (原先的代码还是放在这里,后面有升级版)
    因为从列表头部弹出元素十分耗时,所以放弃它。
    弹出这些元素要花的次数在最坏的情况下最少是8953的阶乘。WTF?!
    所以放弃吧,这样会TLE!但是我们的数据范围不足以让我们MLE。
    经测试,另一种存储诞生了。现在下面不止是两层循环的暴力代码!

    #AC代码1
    n=int(input())
    count=0
    L=[1,2,3]
    for a in L:
        for b in L:
            for c in L:
                for d in L:
                    for e in L:
                        for f in L:
                            for g in L:
                                for h in L:
                                    for i in L:
                                        for j in L:
                                            if a+b+c+d+e+f+g+h+i+j is n:
                                                count=count+1
    if count<1:
        print("0")
    else:
        print(count)
        for a in L:
            for b in L:
                for c in L:
                    for d in L:
                        for e in L:
                            for f in L:
                                for g in L:
                                    for h in L:
                                        for i in L:
                                            for j in L:
                                                if a+b+c+d+e+f+g+h+i+j is n:
                                                    print(a,b,c,d,e,f,g,h,i,j)
    

    因为不足以MLE,所以用list存储还算可以的,并且代码压缩至21行。
    至少不用再次10层循环了耶!

    #AC代码2
    n=int(input())
    L=[1,2,3]#省代码用的
    L2=list([])
    #用来当队列,但是不弹出元素的列表
    for a in L:
     for b in L:
      for c in L:
       for d in L:
        for e in L:
         for f in L:
          for g in L:
           for h in L:
            for i in L:
             for j in L:
              if a+b+c+d+e+f+g+h+i+j is n:
               L2.append([a,b,c,d,e,f,g,h,i,j])
    		   #压入列表
    print(len(L2))#列表长度即统计的个数
    for x in range(len(L2)):
      #逐个输出
      print(L2[x][0],L2[x][1],L2[x][2],L2[x][3],L2[x][4],L2[x][5],L2[x][6],L2[x][7],L2[x][8],L2[x][9])
    

    重新探索,小金羊测试,AC! 果然比原先省下不少时间。


    尾声。

    望大家多多使用队列这个容器做一些类似的需要存储数据的问题。
    类似的问题:营养膳食(优先队列可解)
    不足求指正!小金羊(是个蒟蒻)尽力学习!
    (本题解已更新!界面优化+新代码优化)

  • 相关阅读:
    JNI在C 和 C++ 函数实现的不同
    JNI输出log信息
    Android.mk相关知识
    Android项目编译和使用C语言动态库(so库)
    Jmeter之JDBC请求(四)
    Jmeter之Badboy录制脚本及简化脚本http请求(三)
    Jmeter之录制脚本(二)
    Android自动化压力测试之Monkey Test 异常解读(五)
    Android自动化压力测试之Monkey Test Android常见的错误类型及黑白名单的使用方法(四)
    Android自动化压力测试之Monkey Test (三)
  • 原文地址:https://www.cnblogs.com/jelly123/p/10385963.html
Copyright © 2011-2022 走看看