T2 GMOJ2127. 电子表格

(File IO): input:excel.in output:excel.out

时间限制: 1000 ms  空间限制: 262144 KB  具体限制  

Goto ProblemSet

题目描述

也许你用过Microsoft Excel之类的电子制表软件,这类软件最令人称道的就是强大的公式计算功能。现在希望你也来实现一个具有最基本功能的电子制表软件。表格共有m列(0 < m • 26),从左到右依次用A到Z的大写英文字母表示;有n行(0 < n <100),从上到下依次用1到100的整数表示。这样,每一个单元格的位置就可以唯一地用它所在的列和行表示出来,例如从左到右第3列,从上到下第5行的单元格就可以用“ C5”来表示(注意,这里字母和数字中间没有空格)。
现在对表格进行了一系列的操作,这些操作主要就是赋值和查询。定义操作的输入规则
如下:

  • 每个操作占一行,根据操作类型的不同,每行中可能有二至四个用空格隔开的“单词”;
  • 每行的第一个单词指定了该操作涉及的单元格的位置;
  • 每行的第二个单词指定了相应的操作,可能是: input,output,sum,avg
  •   (1).如果第二个单词是input,表示接下来的一个整数是要赋予该单元格的值,这个值是不超过1000的正整数
  •   (2).如果第二个单词是output,表示你需要在输出文件中输出这个单元格当前的值
  •   (3).如果第二个单词是sum,表示接下来输入的两个单词定义了一个矩形区域,该单元格的值就应该恒为这个矩形区域中所包含的单元格的值的和,直到该单元格被重新定义
  •   (4).如果第二个单词是avg,表示接下来输入的两个单词定义了一个矩形区域,该单元格的值就应该恒为这个矩形区域中所包含的单元格的值的算术平均数,直到该单元格被重新定义;
  • “输入的两个单词定义了一个矩形区域”是指输入一个矩形区域的左上角和右下角的单元格的位置,这样就唯一确定了这个矩形区域;
  • 所有时刻,每个单元格的值均为整数,如果不是,则向下取整;
  • 如果某个单元格的值没有在上文定义,则它的值默认为0;
  • 不会出现循环定义的情况;
  • 在操作过程中所有单元格的值不超过231-1。

输入

第一行输入两个用空格隔开的正整数m和n,分别代表表格的列数和行数。
第二行输入一个正整数s,表示操作的总数。
以下s行每行输入一个操作,具体格式参见问题描述。

输出

对于输入数据的每一个“ output”操作输出一行结果。因此,输出文件的行数等于输入文
件中“ output”操作的个数。

样例输入

3 5
5
A1 input 100
B2 input 200
C3 sum A1 C2
C5 avg B2 C4
C5 output

样例输入

83

数据范围限制

对于30%的数据, m; n; s <= 10;
对于100%的数据, m <= 26, n < =100, s <=100。

Solution

当我看到上面的数据范围限制时,心中无比的开心……

n2暴力,是个地球人都不会TLE吧?

嗯,没错,我Wonderful Answer了了了了了……

本地过,样例太简单了吧……

每次有新的定义时直接计算该单元格的值是错误的,因为sum 和avg 的单元格必须随时更新(题目说明了这样的单元格必须恒等于要求的数值和或平均数)。

神奇的wrong!我也知道呀!

but我用了个栈来存储指令,每次操作后都让它执行一遍的……

大概是要把输入变代码吧。

没错,本地是过了,但是0分呐!

Code

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#define IL inline
using namespace std;
struct node{
int x,y;//输出单元格
bool avg;//0->求和 1->求平均数
int x1,x2,y1,y2;//计算对象
}order[];
int tail=;
string str;
int m,n,s;
int array[][];
int main()
{
// freopen("excel.in","r",stdin);
// freopen("excel.out","w",stdout);
cin>>m>>n>>s;
int x,y;
while(s--)
{
x=getchar();
while(x<'A'||x>'Z'){
x=getchar();
}
x-='A';
y=getchar()-'';
cin>>str;
int i=;
bool flag=;
do{
switch(str[i]){
case 'i':{
int value;
cin>>value;
array[x][y]=value;
break;
}
case 'o':{
cout<<array[x][y]<<endl;
break;
}
case 's':{
order[tail].x=x;
order[tail].y=y; order[tail].avg=; order[tail].x1=getchar();
while(order[tail].x1<'A'||order[tail].x1>'Z') order[tail].x1=getchar();
order[tail].x1-='A';
order[tail].y1=getchar()-''; order[tail].x2=getchar();
while(order[tail].x2<'A'||order[tail].x2>'Z') order[tail].x2=getchar();
order[tail].x2-='A';
order[tail].y2=getchar()-''; tail++;
break;
}
case 'a':{
order[tail].x=x;
order[tail].y=y; order[tail].avg=; order[tail].x1=getchar();
while(order[tail].x1<'A'||order[tail].x1>'Z') order[tail].x1=getchar();
order[tail].x1-='A';
order[tail].y1=getchar()-''; order[tail].x2=getchar();
while(order[tail].x2<'A'||order[tail].x2>'Z') order[tail].x2=getchar();
order[tail].x2-='A';
order[tail].y2=getchar()-''; tail++;
break;
}
default:{
flag=;
break;
}
}
}while(flag&&i++<=); for(int i=;i<tail;i++)
{
int tsa=;
for(int tx=order[i].x1;tx<=order[i].x2;tx++)
for(int ty=order[i].y1;ty<=order[i].y2;ty++)
tsa+=array[tx][ty];
if(order[i].avg) tsa/=(order[i].x2-order[i].x1+)*(order[i].y2-order[i].y1+);
array[order[i].x][order[i].y]=tsa;
}
}
return ;
}

T3

T4 GMOJ1574. X-因子链

(File IO): input:factor.in output:factor.out

时间限制: 1000 ms  空间限制: 131072 KB  具体限制

Goto ProblemSet

题目描述

  给一个正整数X,一个长度为m的X-因子链是指这样一个序列:X0=1,X1,X2,。。。,Xm=X满足:Xi<Xi+1同时Xi|Xi+1(Xi+1能被Xi整除)

  要求X-因子链的最大长度Len和长度为Len的X-因子链的数量。

输出

  一行,两个整数,分别表示最大长度和该长度链的种数。

样例输入

  100

样例输出

  4 6

数据范围限制

(空)

Solution

稍作思考即可

P1问题转化

有一个数列,已知首项(为1)与尾项,每一项都是前一项的整数倍,且每一项都大于前一项。

如何使此数列最长?

设相邻两项的商为k

那么k一定是越小越好

但是所有k之积必须等于尾项

那么,k即为尾项的所有质因数。

所以第一问只需求x的质因数个数。

P1Code

int maxlen=0x3f3f3f3f,kind,x;
int lian[];
IL int prime_factor(int num)
{
int ans=;
if(num==) return ;
if(num==) return ;
int i=;
while(num!=)
{
while(num%i==)
{
num/=i;
ans++;
lian[i]++;
}
i++;
}
return ans;
}

(使用IL(inline)加速调用)

填写lian[i]++是为了第二问的

P2看穿此题

排列组合类型题

因子链的数量,即这些prime factors可以排成多少种

以样例中的100为例

100=2*2*5*5=22*52

那么这串链有两种、四个元素

不去重的话,一共有4!种排列

但是这道题是要问的是种类(即去重的)数量……

现在只观察其中的两个2

2*2*?*?

这时两个2如果交换,会被算入全排列的数量中,但是不能被算入种类数量中!

两个2可以有两种摆放位置的顺序

那么4!=24除去两次2(两个2和两个5的)即可。

若有三个2呢?

三个2可以有3!=3*2*1=6种摆放位置的顺序

把n!除以6即可。

P2数学推导

其中ans为质因数的数量

所以

P2Code

若数据较小(不存在的),可使用dfs暴力枚举

 IL void dfs(int depth)
{
if(depth==maxlen){
kind++;
return;
}
for(int i=;i<=x;i++)
{
if(lian[i]>){
lian[i]--;
dfs(depth+);
lian[i]++;
}
}
}

dfs暴力枚举

于是20分……枉费了我辛辛苦苦思考呀!

阶乘运算

 IL long long factor(int num)
{
if(num==) return ;
long long ans=;
for(int i=;i<=num;i++)
ans*=i;
return ans;
}

factor

如果只是按照普通的阶乘的话,比较容易爆long long

解决方案有两种:

1、预处理(或者打表、记忆化……)出1~20的阶乘(极限应该是31!,但会超过unsigned long long,且数据也没有那么大哈哈),factor函数可用递归。

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#define IL inline
using namespace std;
int lian[];
unsigned long long kind,maxlen=0x3f3f,x;
unsigned long long fact[]={,,,,,,,,,,,,,,,,,,,,};
IL unsigned long long factor(int num)
{
if(fact[num]!=) return fact[num];
return fact[num]=factor(num-)*num;
}

递归加打表

如果记忆化的话,其实就可以不用打表了(反正都是2、3毫秒的样子)。

2、把一个数的阶乘分解成

这样子

用结构体数组储存。

最后要相除则换成相减即可

——来自某某不让我去B组的老师的想法

Code

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#define IL inline
using namespace std;
int lian[];
unsigned long long kind,maxlen=0x3f3f,x;
unsigned long long fact[]={,,,,,,,,,,,,,,,,,,,,};
IL int prime_factor(int num)
{
int ans=;
if(num==) return ;
if(num==) return ;
int i=;
while(num!=)
{
while(num%i==)
{
num/=i;
ans++;
lian[i]++;
}
i++;
}
return ans;
}
IL unsigned long long factor(int num)
{
if(fact[num]!=) return fact[num];
return fact[num]=factor(num-)*num;
}
int main()
{
// freopen("factor.in","r",stdin);
// freopen("factor.out","w",stdout);
scanf("%lld",&x);
maxlen=prime_factor(x);
printf("%lld ",maxlen);
kind=factor(maxlen);
for(unsigned long long i=;i<=sqrt(x);i++)
if(lian[i]>)
kind/=factor(lian[i]);
printf("%lld",kind);
return ;
}

这道题的代码在尝试着极限……0ms,512KB!

可是……真的有0ms……

纪中18日c组模拟赛的更多相关文章

  1. 纪中20日c组模拟赛T1 2121. 简单游戏

    T1 2121. 简单游戏 (File IO): input:easy.in output:easy.out 时间限制: 1000 ms  空间限制: 262144 KB  具体限制 Goto Pro ...

  2. 纪中21日c组模拟赛

    AWSL  AWSL  AWSL  AWSL AWSL  AWSL  AWSL  AWSL AWSL  AWSL  AWSL  AWSL AWSL  AWSL  AWSL  AWSL 题解传送 T1  ...

  3. 纪中20日c组模拟赛

    赛后感想 多写点东西总是好的,但是在最后,算法就不要改动了(就这样我少了10分) 题解 T1 2121. 简单游戏 T2 2122. 幸运票

  4. 洛谷P1880 [NOI1995]石子合并 纪中21日c组T4 2119. 【2016-12-30普及组模拟】环状石子归并

    洛谷P1880 石子合并 纪中2119. 环状石子归并 洛谷传送门 题目描述1 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石 ...

  5. 纪中23日c组T3 2161. 【2017.7.11普及】围攻 斐波那契数列

    2161. 围攻 (File IO): input:siege.in output:siege.out 时间限制: 1000 ms  空间限制: 262144 KB  具体限制   Goto Prob ...

  6. 纪中23日c组T2 2159. 【2017.7.11普及】max 洛谷P1249 最大乘积

    纪中2159. max 洛谷P1249 最大乘积 说明:这两题基本完全相同,故放在一起写题解 纪中2159. max (File IO): input:max.in output:max.out 时间 ...

  7. 纪中21日c组T2 2117. 【2016-12-30普及组模拟】台风

    2117. 台风 (File IO): input:storm.in output:storm.out 时间限制: 1000 ms  空间限制: 262144 KB  具体限制 Goto Proble ...

  8. 纪中20日c组T2 2122. 【2016-12-31普及组模拟】幸运票

    2122. 幸运票 (File IO): input:tickets.in output:tickets.out 时间限制: 1000 ms  空间限制: 262144 KB  具体限制 Goto P ...

  9. 纪中21日c组T1 1575. 二叉树

    1575. 二叉树 (File IO): input:tree.in output:tree.out 时间限制: 1000 ms  空间限制: 262144 KB  具体限制   Goto Probl ...

随机推荐

  1. 曹工说Spring Boot源码(15)-- Spring从xml文件里到底得到了什么(context:load-time-weaver 完整解析)

    写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...

  2. 技术派-github常见的一些用法和缩写

    PR: Pull Request. 拉取请求,给其他项目提交代码 LGTM: Looks Good To Me.  看起来不错,代码已 review,可以合并 SGTM: Sounds Good To ...

  3. oracle和mysql区别

    1.本质的区别.oracle是对象关系数据库管理系统,简称ordbms.mysql是开源关系数据库关系系统,简称rdbms.Oracle是收费的.mysql是开源.免费的. 2.数据库安全性.myql ...

  4. GDI+如何判断一个点是否在区域内

    https://msdn.microsoft.com/en-us/library/windows/desktop/ms533826(v=vs.85).aspx The purpose of hit t ...

  5. HYSBZ_1854_并查集

    http://www.lydsy.com/JudgeOnline/problem.php?id=1854 每次判断每组两个数的根,若不等,则小的遍历1,大的为根,若相等,则说明前面的小的都遍历过,根遍 ...

  6. ELK:收集k8s容器日志最佳实践

    简介 关于日志收集这个主题,这已经是第三篇了,为什么一再研究这个课题,因为这个课题实在太重要,而当今优秀的开源解决方案还不是很明朗: 就docker微服务化而言,研发有需求标准输出,也有需求文件输出, ...

  7. Go语言实现:【剑指offer】二叉搜索树的第k个的结点

    该题目来源于牛客网<剑指offer>专题. 给定一棵二叉搜索树,请找出其中的第k小的结点.例如,(5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4. Go语言实现: ...

  8. Robot Framework自动化测试框架核心指南-如何使用Java编写自定义的RobotFramework Lib

    如何使用Java编写自定义的RobotFramework Lib 本文包括2个章节 1. Robot Frdamwork中如何调用java Lib库 2.使用 java编写自定义的Lib 本文作者为: ...

  9. 常见Bash命令操作

    常见Bash命令操作 查看当前目录 pwd 查看目录下的文件 ls 进入某个目录 cd 返回上一级目录 cd .. 创建一个目录 mkdir abc 创建一个文件 touch a.html 保存文件退 ...

  10. javascript 原生js对html元素的 增删改查 操作

    'use strict'; class View{ constructor(){ } //创建html元素 addEl(fel, elemName, id, cls){ //创建一个元素 let el ...