题解 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\n",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! 果然比原先省下不少时间。


尾声。

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

转载于:https://www.cnblogs.com/jelly123/p/10385963.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值