【思考题】great cells(数学)

【思考题】great cells(数学)

【题目链接】https://odzkskevi.qnssl.com/e4ddab4bbddb4d48602cd7ef31d6c6fa?v=1504573247
H题


题目内容

这里写图片描述
这里写图片描述


题目大意

有n行m列格子,可以填的数是1-g,如果一个数比它所在行列的其他所有数都大,这个数是great number,Ag表示有g个great number 的情况。求:这里写图片描述


解题思路

把原式拆分成(A0+A1+……+Ag)+(1*A1+2*A2+……+g*Ag),前半部分即为g的n*m次方,后半部分每一项都是 great number数 乘 情况数,相当于鸡蛋数 乘 装鸡蛋的篮子数 等于 总鸡蛋数,所以后半部分可以转化成每个数在每一位置成为great number 的次数。
后半部分具体转化为g^(m-1) * (n-1) * (1^(m+n_2) + 2^(m+n-2) + …… + (g-1)^(m+n-2))。
公式是从二开始的,对于小数据要特判。


AC代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<string>
#include<algorithm>
#include<math.h>
#include<limits.h>
#include<stack>
#include<queue>
#define LL long long
using namespace std;

const LL mod=1e9+7;
LL fast_power(LL a,LL b)
{
    LL ans=1;
    while(b>0)
    {
        if(b&1) ans=ans*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}
int main()
{
    int t;
    LL n,m,g;
    scanf("%d",&t);
    for(int kk=1;kk<=t;kk++)
    {
        scanf("%lld%lld%lld",&n,&m,&g);
        if(n==1&m==1)
        {
            printf("Case #%d: %lld\n",kk,2*g);
            continue;
        }
        if(g==1)
        {
            printf("Case #%d: 1\n",kk);
            continue;
        }
        LL a,b,c=0;
        a=fast_power(g,n*m);
        b=fast_power(g,(n-1)*(m-1));
        for(LL i=1;i<g;i++)
        {
            c+=fast_power(i,m+n-2);
            c%=mod;
        }
        c=c*n*m%mod;
        LL ans=a+b*c%mod;
        ans%=mod;
        printf("Case #%d: %lld\n",kk,ans);
    }
}
### 思考题Q1 #### 题目重述 为什么使用`map`实现的商品管理系统可拓展性很差?如果采用上述实现,现在要添加一个新的商品,该如何更改?如果是为商品增填一个新的“简介”属性,又该如何更改? #### 详解 使用`map`实现的商品管理系统可拓展性差的原因在于: - 添加新商品时,需要手动修改`map`中的键值对,增加了代码的硬编码量。 - 增加新属性(如“简介”)时,需要重新设计整个数据结构,无法灵活扩展。 而使用面向对象方法,可以通过增加新类来实现,无需改动已有代码,符合开闭原则。 #### 知识点 1. **开闭原则**:软件实体应该对扩展开放,对修改关闭。通过继承和组合,可以在不修改现有代码的基础上添加新功能。 2. **面向对象编程**:通过类和对象实现更灵活的数据管理,增强代码的可维护性和可拓展性。 --- ### 思考题Q2 #### 题目重述 为什么我们不使用继承来完成设计?也即,为什么我们不设计“珍珠奶茶”、“椰果奶茶”、“珍珠椰果奶茶”等类,让他们继承奶茶类(奶茶类当然继承饮品类),然后对其他品类的饮品也做这样的实现? #### 详解 使用继承来实现上述需求会导致以下问题: - **类爆炸**:每种组合都需要一个新类,导致类的数量急剧增加,难以管理和维护。 - **重复代码**:每个子类都会重复父类的功能,违反了DRY原则(Don't Repeat Yourself)。 - **灵活性差**:如果需要新增一种小料或饮品,必须创建大量新类,不利于扩展。 相比之下,使用组合方式可以避免这些问题,通过将小料和饮品作为独立类进行组合,增强了代码的灵活性和可维护性。 #### 知识点 1. **组合优于继承**:组合可以避免类爆炸,增强代码的灵活性和可维护性。 2. **面向对象设计原则**:遵循单一职责原则和开放封闭原则,提高代码质量。 --- ### 思考题Q3 #### 题目重述 上述代码在调用`great_great_triple_milktea->cost()`时发生了什么?请用自然语言描述或者画出调用图。 #### 详解 当调用`great_great_triple_milktea->cost()`时,发生了以下过程: 1. `great_great_triple_milktea`是一个由`Nata(Pudding(Pearl(MilkTea)))`组成的对象。 2. 首先调用`Nata`的`cost()`方法,计算结果为`Pearl`的`cost()` + `Nata`的`cost()`。 3. 接着调用`Pearl`的`cost()`方法,计算结果为`MilkTea`的`cost()` + `Pearl`的`cost()`。 4. 最终结果为`MilkTea`的`cost()` + `Pearl`的`cost()` + `Pudding`的`cost()` + `Nata`的`cost()`。 调用图如下: ```plaintext great_great_triple_milktea->cost() | V Nata->cost() -> Pearl->cost() -> Pudding->cost() -> MilkTea->cost() ``` #### 知识点 1. **装饰器模式**:通过层层装饰对象,动态地添加行为或责任。 2. **递归调用**:每个装饰器类调用其基类的方法,逐步累加结果。 --- ### 思考题1 #### 题目重述 请画出上述两种实现方法的类图(只需要画酒吧类和可能存在的工厂类),总结简单工厂模式和工厂方法模式之间的区别和联系。 #### 详解 #### 类图 ##### 工厂方法模式 ```plaintext Bar ├── BJBar │ └── create_cocktail() └── SHBar └── create_cocktail() ``` ##### 简单工厂模式 ```plaintext Bar ├── BJBar └── SHBar CocktailFactory ├── BJCocktailFactory └── SHCocktailFactory ``` #### 区别与联系 - **工厂方法模式**:父类声明一个工厂方法,由子类具体实现。这种方式将创建逻辑分散到各个子类中,适合有多个不同类型的对象创建场景。 - **简单工厂模式**:通过引入一个专门的工厂类来集中管理对象创建逻辑。这种方式减少了类之间的耦合,但工厂类可能变得过于庞大。 #### 知识点 1. **工厂方法模式**:适用于多个子类需要实现相同接口的情况,分散创建逻辑。 2. **简单工厂模式**:集中管理对象创建逻辑,降低类间耦合。 --- ### 思考题2 #### 题目重述 为什么我们不直接定义基类的构造函数为`init()`函数中的内容? #### 详解 直接将基类的构造函数定义为`init()`函数中的内容会导致以下问题: - **重复代码**:每次创建子类时都需要复制相同的初始化代码。 - **维护困难**:如果初始化逻辑发生变化,需要同步修改所有子类。 - **违背开闭原则**:增加了代码的修改成本,降低了扩展性。 通过将初始化逻辑封装在`init()`方法中,可以保持构造函数的简洁,并在需要时方便地进行扩展和维护。 #### 知识点 1. **开闭原则**:保持对扩展开放,对修改关闭,便于维护和扩展。 2. **封装**:将初始化逻辑封装在方法中,减少重复代码。 --- ### 思考题3 #### 题目重述 请画出上述两种抽象工厂模式的类图(子类只需要画干马天尼或者任意一杯你喜欢的酒,其他子类用省略号代替即可),并简述简单工厂模式、工厂方法模式、抽象工厂模式之间的关系和差异。 #### 详解 #### 类图 ##### 继承方式(多个工厂方法) ```plaintext Cocktail ├── BJDryMartini │ └── create_name(), create_flavors(), ... └── SHDryMartini └── create_name(), create_flavors(), ... ``` ##### 组合方式(大的简单工厂模式) ```plaintext Cocktail └── BJDryMartini └── SHDryMartini IngredientFactory ├── BJDryMartiniIngredientFactory └── SHDryMartiniIngredientFactory ``` #### 关系与差异 - **简单工厂模式**:集中管理对象创建逻辑,适用于单一类型的对象创建,耦合度较高。 - **工厂方法模式**:将创建逻辑分散到各个子类中,适合多种类型的对象创建,扩展性强。 - **抽象工厂模式**:不仅创建单一类型的对象,还可以创建一系列相关或依赖的对象,适用于复杂对象的创建,耦合度低。 #### 知识点 1. **抽象工厂模式**:创建一系列相关或依赖的对象,适合复杂对象的创建。 2. **工厂模式**:集中或分散管理对象创建逻辑,提升代码的可维护性和扩展性。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值