【普及组_在线赛】最小与最大
来源:互联网 发布:语音模拟软件 编辑:程序博客网 时间:2024/06/03 23:43
【普及组_在线赛】最小与最大
描述
题目描述
做过了乘积最大这道题,相信这道题也难不倒你。
已知一个数串,可以在适当的位置加入乘号(设加了k个,当然也可不加,即分成k+1个部分),设这k+1个部分的乘积(如果k=0,则乘积即为原数串的值)对m 的余数(即mod m)为x;
现求x能达到的最小值及该情况下k的最小值,以及x能达到的最大值及该情况下的k的最小值(可以存在x的最小值与最大值相同的情况)。输入
第一行为数串,长度为n 满足2<=n<=1000,且数串中不存在0;
第二行为m,满足2<=m<=50。输出
四个数,分别为x的最小值 和 该情况下的k,以及x的最大值和 该情况下的k,中间用空格隔开。
样例输入
4421
22样例输出
0 1 21 0
分析
这题看着像数论,实际上是DP。
首先要知道,做这题完全无须高精度(包括暴力)。
借鉴一下人人皆知的读入优化:
如果有个数为a,你要在末尾安上一个b,那么得出的值是
然后直接取模。
这题m很小,是AC的关键。
设
什么意思?
我们枚举i时,前面有些数时分好的,但是还有一段你要继续在后面安数,这一段就是没分好的。
初始化:
如何从
考虑两种情况:
1. k后面安上第
2. 在i和
求出所有
然后统计答案就行了。
注意,因为这是段数,所以最后记得
这样就可以简单粗暴地AC了。
时间复杂度
代码
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;char str[1007];int m;int f[1001][51][51];int main(){ freopen("minmax.in","r",stdin); freopen("minmax.out","w",stdout); scanf("%s",str+1);//字符串读入 int len=strlen(str+1); scanf("%d",&m); int i,j,k; f[1][1][(str[1]-'0')%m]=1;//初始化 int *q,*p; for (i=1;i<len;++i) for (j=0;j<=m;++j) for (k=0;k<=m;++k) { q=&f[i][j][k];//利用指针优化寻址 if (*q) { p=&f[i+1][j][(k*10+str[i+1]-'0')%m]; if (*p) *p=min(*p,*q); else *p=*q; p=&f[i+1][j*k%m][(str[i+1]-'0')%m]; if (*p) *p=min(*p,*q+1); else *p=*q+1; } } int s,mins=2147483647,mins_k,maxs=-2147483648,maxs_k; for (i=0;i<=m;++i)//统计答案 for (j=0;j<=m;++j) { q=&f[len][i][j]; if (*q) { s=i*j%m; if (s<mins) { mins=s; mins_k=*q; } else if (s==mins) mins_k=min(mins_k,*q); if (s>maxs) { maxs=s; maxs_k=*q; } else if (s==maxs) maxs_k=min(maxs_k,*q); } } printf("%d %d %d %d\n",mins,mins_k-1,maxs,maxs_k-1);}
注意事项
- 为什么我要设段数?因为
段数>0 ,所以不用一开始赋特殊值。 - 为什么用指针?优化寻址,加快程序速度
- 题外话:我第一次交时RE,95分。调好久后发现是枚举i时将
<len 打成<=len ,好尴尬! - 题外话:我后来赋初值减少了些if语句,不知为何却慢了;我还用队列优化一下DP,存有用状态也更慢了。我第一次AC时f的每个节点多设了一个标记,但没必要。
- 我的方法跟别人不同,他们设两维状态。但是他们时间复杂度
O(n2m) ,我的O(nm2) ,明显更优。
- 【普及组_在线赛】最小与最大
- OIBH杯第三次普及组模拟赛T2 最小花费
- 1162. 【普及组模拟赛】最大杂置(set)
- 最小与最大
- wikioi 1017 乘积最大 普及组 2000
- NOIP 2000普及组 乘积最大 详解
- 最大公倍数与最小公约数
- 最小堆与最大堆
- 最小堆与最大堆
- 2017.1.13【初中部 】普及组模拟赛C组 money 最小花费 题解
- JZOJsenior2016.2017.04.08【NOIP 普及组】模拟赛C组 T2最小步数
- 【DayDayUp】【算法_图_网络流_之二_Dinic层次图与最小费最大流的概述】(待续)
- 利用最大堆和最小堆在线寻找中位数
- 2017.1.13【初中部 】普及组模拟赛C组 maxsum 最大约数和 题解
- OIBH杯第三次模拟赛(普及组)Problem 3 : maxsum 最大约数和
- OIBH杯第三次普及组模拟赛T3 最大约数和
- 排序算法_堆排序(最大堆、最小堆)
- MATLAB图像处理_统计最大/最小/平均灰度
- XGBoost Parameters
- 双向链表-插入元素
- oracle创建用户
- Java 语言的发展历程
- TCP/IP 层次
- 【普及组_在线赛】最小与最大
- Java之I/O处理
- Scala基础之for循环,函数,Lazy关键字
- 基于Unity3D的相机功能的实现(七)—— 综合篇
- [POJ](2236)Wireless Network ---- 并查集
- Vim的升级与配置
- 1225: 字符串的修改
- Ubuntu 17.10 安装 cuda 9.0 之 deb
- transform 3D 变换