题目描述 Description
丁丁最近沉迷于一个数字游戏之中。这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易。游戏是这样的,在你面前有一圈整数(一共n个),你要按顺序将其分为m个部分,各部分内的数字相加,相加所得的m个结果对10取模后再相乘,最终得到一个数k。游戏的要求是使你所得的k最大或者最小。
例如,对于下面这圈数字(n=4,m=2):
当要求最小值时,((2-1) mod 10)×((4+3) mod 10)=1×7=7,要求最大值时,为((2+4+3) mod 10)×(-1 mod 10)=9×9=81。特别值得注意的是,无论是负数还是正数,对10取模的结果均为非负值。
丁丁请你编写程序帮他赢得这个游戏。
输入描述 Input
Description
输入文件第一行有两个整数,n(1≤n≤50)和m(1≤m≤9)。以下n行每行有个整数,其绝对值不大于104,按顺序给出圈中的数字,首尾相接。
输出描述 Output
Description
输出文件有两行,各包含一个非负整数。第一行是你程序得到的最小值,第二行是最大值。
样例输入 Sample
Input
4 2
4
3
-1
2
样例输出 Sample
Output
7
81
数据范围及提示 Data Size &
Hint
en
分类标签 Tags 点此展开
注意:这里的负数mod
10,是把负数加10,一直加到这个数大于10,再返回x就是了。
代码:
#include<
iostream >
using namespace
std;
#include<
cstdio >
#include<
cmath >
#include<
cstring >
#include<
cstdlib >
#define INFn
51
#define INF
99999999
#define MIN
-99999999
#define INFm
10
long long
min(long long a,long long b)
{
return
a>b?b:a;
}
long long
max(long long a,long long b)
{
return
a>b?a:b;
}
long long
mod(long long x)
{
if(x>=0)
return x;
else
{
while(x<0)
{
x+=10;
}
return x;
}
}
long long
dpmin[INFn][INFm],dpmax[INFn][INFm],sum[INFn];
int
num[INFn],n,m;
long long
ansmax=MIN,ansmin=INF;
void chuli(int
i)
{
if(i==1) return
;
else {
int
t=num[n];
for(int
i=n-1;i>=1;--i)
num[i+1]=num[i];
num[1]=t;
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int
i=1;i<=n;++i)
scanf("%d",&num[i]);
for(int
i=1;i<=n;++i)
{
chuli(i);
memset(sum,0,sizeof(sum));
memset(dpmin,0,sizeof(dpmin));
memset(dpmax,0,sizeof(dpmax));
for(int
i=1;i<=n;++i)
sum[i]=sum[i-1]+num[i];
for(int
i=1;i<=n;++i)
dpmax[i][1]=dpmin[i][1]=mod(sum[i]);
for(int
j=2;j<=m;++j)
ansmin=min(ansmin,dpmin[n][m]);
ansmax=max(ansmax,dpmax[n][m]);
}
cout<<ansmin<<endl<<ansmax;
return 0;
}