uoj#P642. 【美团杯2021】F. 面向对象

【美团杯2021】F. 面向对象

虽然在算法竞赛中不常用,但是面向对象确实是 c++ 编程中非常重要的一部分。

面向对象

在北京大学信科的培养方案中,面向对象编程是每一名本科生的必修课。今天,蒜斜在整理他以前的课程资料的时候,找到了他学习面向对象编程时的大作业代码。然而,因为一些未知的原因,代码里的一些内容丢失了。

于是蒜斜找到了你,希望你能帮他复原一下这个代码。复原的方式有很多,于是他希望你能告诉他不同的复原方式有多少种。

问题描述

给出一个损坏的 c++ 代码。因为数据丢失的原因,这个代码里存在一些未知的空缺。空缺有两类:

  1. 修饰符空缺,用 /*MissingModifier*/ 表示。在原本程序中,这一类空缺对应的一定是标识符 private, protectedpublic 中的一个。
  2. 函数空缺,用 /*MissingMethod*/ 表示。在原本程序中,这一类空缺对应的一定是一个形如 method#Num 的函数名,其中 #Num 对应了一个正整数。

给定一个损坏的 c++ 代码,你需要计算有多少种填写空缺的方案,使得填写后的程序是可以正常通过编译的。这个方案数可能会很大,因此你只需要输出方案数对 $998244353$ 取模后的结果。

例子

下面给出了一个损坏的 c++ 代码。

class Class1 {
  void method1() {
    /*MissingMethod*/();
  }
  /*MissingModifier*/:
  void method2() {}
};
class Class2: /*MissingModifier*/ Class1 {
  /*MissingModifier*/:
  void method3() {}
  /*MissingModifier*/:
  void method4() {}
};
int main() {
  Class2 o2;
  o2./*MissingMethod*/();
}

我们按照从上到下的顺序依次把 /*MissingModifier*/ 命名为 $x_1, x_2,x_3,x_4$,把 /*MissingMethod*/ 命名为 $y_1,y_2$。不难发现 $y_1$ 的填法和其他空缺的填法无关,它始终可以取 method1 或者 method2。因此我们可以先忽略这个空缺,然后在最后把答案乘以 $2$。

对 $y_2$ 的取值分类讨论:

  1. method1。这时一定无法编译通过,因为 method1Class1 的私有函数。
  2. method2。因为是通过 O2 调用的 method2,所以可以得到 $x_1,x_2$ 一定都是 public。此时对 $x_3,x_4$ 的填法没有要求,因此方案数为 $9$。
  3. method3。可以得到 $x_3$ 一定是 public。此时对 $x_1,x_2,x_4$ 的填法没有要求,因此方案数为 $27$。
  4. method4。与 method3 同理,可以得到方案数为 $27$。

因此,总的方案数为 $(9+27+27) \times 2 = 126$。

限制与约定

本题的两个部分各给出了一个部分程序(见下发文件下载),分别为 oo1.inoo2.in。对于每一个部分,你只需要提交一个数字,表示对应部分程序的答案。

为了节约大家的时间,这儿给出输入程序的一部分性质:

  1. 保证存在一种填写空缺的方法可以使得输入程序能够通过编译。
  2. 输入程序中除了主函数 main 以外,所有的函数均为成员函数。
  3. 输入程序中没有使用虚函数和静态函数。
  4. 输入程序中所有的修饰符 public, protectedprivate 均被替换为了空缺 /*MissingModifier*/
  5. 输入程序中所有的函数调用均被替换为了空缺 /*MissingMethod*/,所有函数声明中的函数名均没有被替换。
  6. 输入程序中所有类按照出现顺序依次命名为 Class1, Class2 等等。所有成员函数按照出现顺序依次命名为 method1, method2 等等。
  7. 除了 Class1 以外,其他所有类均有一个父类。
  8. 所有类均不包含任何成员变量。
  9. 输入程序中类的数量不超过 $300$ 个,成员函数总数以及函数调用总数不超过 $1000$ 个。

在 small task 中,输入程序 oo1.in 还保证:

  1. 主函数 main 为空。
  2. 在每一个成员函数的声明之前,均有一个修饰符空缺 /*MissingModifier*/:

下载

输入程序下载