阶乘位数

题目描述

如图p1.jpg所示,3 x 3 的格子中填写了一些整数。

我们沿着图中的红色线剪开,得到两个部分,每个部分的数字和都是60。

本题的要求就是请你编程判定:对给定的m x n 的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。
如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。
如果无法分割,则输出 0

程序输入输出格式要求:

程序先读入两个整数 m n 用空格分割 (m,n<10)

表示表格的宽度和高度

接下来是n行,每行m个正整数,用空格分开。每个整数不大于10000

程序输出:在所有解中,包含左上角的分割区可能包含的最小的格子数目。

例如:

用户输入:

3 3

10 1 52

20 30 1

1 2 3

则程序输出:

3

再例如:

用户输入:

4 3

1 1 1 1

1 30 80 2

1 1 1 100

则程序输出:

10

(参见p2.jpg)

资源约定:

峰值内存消耗(含虚拟机) < 64M

CPU消耗 < 5000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

注意:不要使用package语句。不要使用jdk1.6及以上版本的特性。

注意:主类的名字必须是:Main,否则按无效代码处理。



PS:

1.输入m行n列,存入二维数组arr[n][m]及一维数组array[m*n]

2.总价为奇数时,输出0.总价为偶数时,到步骤3.

3.用动态规划得到总和为count/2的最优解,每次得到最优解时进行步骤4的验证.

4.将步骤3得到的最优解记录到一个flag[m][n]中,对标记在flag中的格子进行深度遍历,若连通说明符合条件,然后对未被标记在flag中的格子也进行深度遍历,若连通说明格子确实被分成了两部分而不是更多的部分.这样就成功验证了.

5.输出步骤3中验证成功并且最终最优的那个解的格子数.

注意,这道题难点在于剪开的必须是"两部分",如果是其中一部分是连通的,但可能把另一部分截断,如:

4 4

20 30 40 1

110 1 10 1

1 2 10 1

1 1 10 1

这种情况是不符合的,而且很难验证.本程序反过来先算值为total/2的两部分,然后分别计算连通,这种思路比较清晰.

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner; public class t9 {
static int n,m;
static int[][] arr;
static int[] array;
static boolean[][] flag;
static boolean[][] visit;
static int total=0;
static int result=0;
static int finalResult=Integer.MAX_VALUE;
static int index=0; public static void main(String[] args){
Scanner sc=new Scanner(System.in);
Scanner sc2=new Scanner(sc.nextLine()).useDelimiter("\\s*"); m=sc2.nextInt(); //列
n=sc2.nextInt(); //行
arr=new int[n][m];
array=new int[n*m];
flag=new boolean[n][m];
for(int i=0;i<n;i++){
sc2=new Scanner(sc.nextLine());
for(int j=0;j<m;j++){
arr[i][j]=sc2.nextInt();
array[index++]=arr[i][j];
total+=arr[i][j];
}
} if(total%2!=0 || array[0]>total/2){ //奇数不可分割
System.out.println(0);
}else{
flag[0][0]=true;
result++;
dp(total/2-array[0],1);
if(finalResult==Integer.MAX_VALUE) finalResult=0;
System.out.println(finalResult);
}
} public static void dp(int count, int start){ //动态规划,找到和等于total/2的情况并验证,取最优解
if(count==0){ //和为total/2的情况
if(confirm() && finalResult>result){
finalResult=result; //验证并取最优解
return;
}
}
for(int i=start;i<index;i++){
if(count>=array[i]){
count-=array[i];
flag[i/m][i%m]=true; //访问过,标记
result++;
dp(count,i+1); //..i+1
count+=array[i]; //退栈时注意还原
flag[i/m][i%m]=false;
result--;
}
}
} public static boolean confirm(){ //验证是否是连通图
for(int i=0;i<n;i++){ //..打印这种情况
for(int j=0;j<m;j++){
System.out.print(flag[i][j]+" ");
}
System.out.println();
}
System.out.println(); int row=0,col=0;
visit=new boolean[n][m];
for(int i=1;i<index;i++){ //找到一个属于"另一部分"的方格
if(flag[i/m][i%m]==false){
row=i/m;
col=i%m;
break;
}
}
if(dfs(0,0,1)==result && dfs(row,col,0)==index-result){ //两部分都为连通图,则满足题意
return true;
}
else{
return false;
}
} public static int dfs(int row, int col, int f){
int num1=0;
int num2=0;
int num3=0;
int num4=0;
if(f==1 && flag[row][col]==true){ //包含左上角方块的部分
visit[row][col]=true;
if(row+1<n && !visit[row+1][col]) num1=dfs(row+1,col,1);
if(col+1<m && !visit[row][col+1]) num2=dfs(row,col+1,1);
return num1+num2+1;
}else if(f==0 && flag[row][col]==false){ //另外一部分
visit[row][col]=true;
if(row+1<n && !visit[row+1][col]) num1=dfs(row+1,col,0);
if(col+1<m && !visit[row][col+1]) num2=dfs(row,col+1,0);
if(row-1>=0 && !visit[row-1][col]) num3=dfs(row-1,col,0);
if(col-1>=0 && !visit[row][col-1]) num4=dfs(row,col-1,0);
return num1+num2+num3+num4+1;
}else{
return 0;
}
}
}

java实现第四届蓝桥杯阶乘位数的更多相关文章

  1. Java实现第九届蓝桥杯阶乘位数

    阶乘位数 题目描述 小明维护着一个程序员论坛.现在他收集了一份"点赞"日志,日志共有N行.其中每一行的格式是: ts id 表示在ts时刻编号id的帖子收到一个"赞&qu ...

  2. java实现第七届蓝桥杯阶乘位数

    阶乘位数 阶乘位数 9的阶乘等于:362880 它的二进制表示为:1011000100110000000 这个数字共有19位. 请你计算,9999 的阶乘的二进制表示一共有多少位? 注意:需要提交的是 ...

  3. java实现第四届蓝桥杯剪格子

    剪格子 题目描述 如图p1.jpg所示,3 x 3 的格子中填写了一些整数. 我们沿着图中的红色线剪开,得到两个部分,每个部分的数字和都是60. 本题的要求就是请你编程判定:对给定的m x n 的格子 ...

  4. java实现第四届蓝桥杯公式求值

    公式求值 输入n, m, k,输出图1所示的公式的值.其中C_n^m是组合数,表示在n个人的集合中选出m个人组成一个集合的方案数.组合数的计算公式如图2所示. 输入的第一行包含一个整数n:第二行包含一 ...

  5. java实现第四届蓝桥杯危险系数

    危险系数 抗日战争时期,冀中平原的地道战曾发挥重要作用. 地道的多个站点间有通道连接,形成了庞大的网络.但也有隐患,当敌人发现了某个站点后,其它站点间可能因此会失去联系. 我们来定义一个危险系数DF( ...

  6. java实现第四届蓝桥杯猜灯谜

    猜灯谜 题目描述 A 村的元宵节灯会上有一迷题: 请猜谜 * 请猜谜 = 请边赏灯边猜 小明想,一定是每个汉字代表一个数字,不同的汉字代表不同的数字. 请你用计算机按小明的思路算一下,然后提交&quo ...

  7. java实现第四届蓝桥杯大臣的旅费

    大臣的旅费 题目描述 很久以前,T王国空前繁荣.为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市. 为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大 ...

  8. java实现第四届蓝桥杯梅森素数

    梅森素数 题目描述 如果一个数字的所有真因子之和等于自身,则称它为"完全数"或"完美数" 例如:6 = 1 + 2 + 3 28 = 1 + 2 + 4 + 7 ...

  9. java实现第四届蓝桥杯连号区间数

    连号区间数 题目描述 小明这些天一直在思考这样一个奇怪而有趣的问题: 在1~N的某个全排列中有多少个连号区间呢?这里所说的连号区间的定义是: 如果区间[L, R] 里的所有元素(即此排列的第L个到第R ...

随机推荐

  1. 使用github作为maven仓库存放发布自己的jar包依赖 实现多个项目公共部分代码的集中,避免团队中多个项目之间代码的复制粘贴

    使用github作为maven仓库存放发布自己的jar包依赖 实现多个项目公共部分代码的集中,避免团队中多个项目之间代码的复制粘贴. 1.首先在本地maven位置的配置文件setting.xml(没有 ...

  2. python 利用 for ... else 跳出双层嵌套循环

    背景 周末在写一个爬虫时,遇到这样一种场景:从搜索结果中下载指定数量的文件 例如:搜索结果中共分为10页展示,加起来一共50条数据,现在要做的是从50条数据中下载指定数量的数据 为了实现这个功能,开始 ...

  3. 4、post请求(json)

    前言上一篇讲过get请求的参数都在url里,post的请求相对于get请求多了个body部分,本篇就详细讲解下body部分参数的几种形式. 一.body数据类型 常见的post提交数据类型有四种: 1 ...

  4. Spring MVC 函数式编程进阶

    1. 前言 上一篇对 Spring MVC 的函数式接口编程进行了简单入门,让很多不知道的同学见识了这种新操作.也有反应这种看起来没有传统写法顺眼,其实大家都一样.但是我们还是要敢于尝试新事物.Jav ...

  5. Excel 数据导入至Sqlserver 数据库中 ltrim() 、rtrim() 、replace() 函数 依次空格无效问题

    今天导一些数据从Excel中至Sqlserver 数据库中,在做数据合并去重的时候发现,有两条数据一模一样,竟然没有进行合并: 最后发现有一条后面有个“空格”,正是因为这个“空格”让我抓狂许久,因为它 ...

  6. ssh别名登录,非常适合从跳板机登录其他主机

    一般连主机会是这样的: ssh admin@IP 端口变了的话还要加上端口号 ssh admin@IP -p 10022 可以用ssh别名简化这个操作: vim .ssh/config 想要全局生效的 ...

  7. POJ3693 Maximum repetition substring 后缀数组

    POJ - 3693 Maximum repetition substring 题意 输入一个串,求重复次数最多的连续重复字串,如果有次数相同的,则输出字典序最小的 Sample input ccab ...

  8. Spring @Qualifier 注释

    可能会有这样一种情况,当你创建多个具有相同类型的 bean 时,并且想要用一个属性只为它们其中的一个进行装配. 在这种情况下,你可以使用 @Qualifier 注释和 @Autowired 注释通过指 ...

  9. ShoneSharp语言(S#)软件更新13.6版

    ShoneSharp语言(S#)编辑解析运行器 软件更新13.6版 作者:Shone 今天把近期发现的各种软件问题做了修改,并发布新版ShoneSharp.13.6.exe,最新的网盘链接为: htt ...

  10. 【github龟速克星】如何下载快如闪电

    详见:https://www.kesci.com/home/project/5e96fe1ae7ec38002d03cd56 借助第三方网站:https://g.widora.cn/