题目描述
丁丁最近沉迷于一个数字游戏之中。这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易。游戏是这样的,在你面前有一圈整数(一共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取模的结果均为非负值。
丁丁请你编写程序帮他赢得这个游戏。
输入输出格式
输入格式:
输入文件第一行有两个整数,n(1≤n≤50)和m(1≤m≤9)。以下n行每行有个整数,其绝对值不大于10^4104 ,按顺序给出圈中的数字,首尾相接。
输出格式:
输出文件有两行,各包含一个非负整数。第一行是你程序得到的最小值,第二行是最大值。
输入输出样例
输入样例#1:
4 2
4
3
-1
2
输出样例#1:
View Code
7
81
1 #include <iostream> 2 #include <cstdio> 3 #include <string> 4 #include <algorithm> 5 #include <stdlib.h> 6 7 using namespace std; 8 int circle[60],n,m;//n num m part 9 int maxn=0,minn=9999; 10 int tmpnow=1; 11 12 int pow(int k,int n){ 13 for(int i=1;i<=k;i++) 14 n*=9; 15 return n; 16 } 17 18 int mod(int n){ 19 if(n<0)n+=100000; 20 return n%10; 21 } 22 23 void dfs(int first,int layer,int res){//first是现在要分的部分的第一个数字编号 layer是现在在分第几组 res是还剩多少数字没分(包括first) 24 if(pow(m-layer+1,tmpnow)<=maxn&&tmpnow>=minn)return; 25 if(layer==m){ 26 int plus=0; 27 for(int i=0;i<res;i++) 28 plus+=circle[(i+first)%n]; 29 plus=mod(plus); 30 int tmp=tmpnow; 31 tmpnow*=plus; 32 maxn=max(tmpnow,maxn); 33 minn=min(tmpnow,minn); 34 tmpnow=tmp; 35 return; 36 } 37 int reslayer=m-layer; 38 reslayer=res-reslayer; 39 int tmpsum=0; 40 for(int i=0;i<reslayer;i++) 41 { 42 tmpsum+=circle[(i+first)%n]; 43 tmpsum=mod(tmpsum); 44 int tmp=tmpnow; 45 tmpnow*=tmpsum; 46 dfs((i+first+1)%n,layer+1,res-1-i); 47 tmpnow=tmp; 48 } 49 } 50 51 int main() 52 { 53 scanf("%d%d",&n,&m); 54 for(int i=0;i<n;i++) 55 scanf("%d",&circle[i]); 56 for(int i=0;i<n;i++) 57 dfs(i,1,n); 58 printf("%d %d ",minn,maxn); 59 return 0; 60 }
有一点比较重要的是略微用了下剪枝(但不知道不用能不能过,感觉差不多其实,都挺暴搜的)
一开始因为在做除法的时候没有当心,有除数是0的数据,于是RE
应该可以用dp做,有时间再补