• 18.04.11 luoguP1043 数字游戏


    题目描述

    丁丁最近沉迷于一个数字游戏之中。这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易。游戏是这样的,在你面前有一圈整数(一共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:
    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 }
    View Code

    有一点比较重要的是略微用了下剪枝(但不知道不用能不能过,感觉差不多其实,都挺暴搜的)

    一开始因为在做除法的时候没有当心,有除数是0的数据,于是RE

    应该可以用dp做,有时间再补

    注定失败的战争,也要拼尽全力去打赢它; 就算输,也要输得足够漂亮。
  • 相关阅读:
    bus总线
    vue 动态组件、父子组件传参
    echarts
    记录板
    留言板
    如何移除双系统mac中的windows系统
    Kernel,Shell,Bash 的关系
    zju 校队选拔 被虐记
    COGS 2638. 数列操作ψ 线段树
    退役公告【现已复活】
  • 原文地址:https://www.cnblogs.com/yalphait/p/8798742.html
Copyright © 2020-2023  润新知