挑战 渣打科营“Mini Code Marathon”赛题:连通块最少
package csdn;
/**
* 渣打科营“Mini Code Marathon”赛题:连通块最少
* @author Cheeps
* 思路:在同一个全1连通块中,任何两个1的最小距离等于他们下标的距离减一,即任何两个1之间的路径,
* 在只能往前走,不能往后退,无论纵向或横向,一旦有回退的步骤,最小距离必然会大于他们下标的距离减一
* 故而要保证任何两个1的最小距离等于他们下标的距离减一就是要保证任何同行或同列的1之间没有0
* 那么一旦同行或同列中两个1之间有0把这些0变成1即可达到题目要求
* 主要方法:getConnectedOnes(n,m)每次得到一个全1连通子图
* countChanges(n,m)得到一个全1连通子图变合法需要改变的0的个数
* 操作流程:根据提示输入01矩阵的行、列,用户输入01矩阵后,程序先打印出该矩阵合法的连通矩阵,根据用户的选择输入下一组测试数据或输出结果
*/
public class ConnectedOnes {
static int[][]metric = new int[50][50];//01矩阵
static int ones = 0;//记录整个01矩阵中1的个数,每次找到一个连通子图时把这个子图包含的所有1全部变为2,ones也相应减少,当ones重新为0时01矩阵也就合法了
/**
* 得到01矩阵中的全1连通块数组,得到的signal数组中标记为1的为一个全1连通块
* 核心:遍历矩阵,遇到的第一个1,令它属于连通子图,是否为第一个1用start来标示
* 对于以后遇到的每个1,如果它的左、上方元素中有一个属于连通子图,则这个1也属于连通子图
* @param n
* @param m
* @return signal
*/
private static int[][] getConnectedOnes(int n,int m){
boolean start = true;//判断是否为连通图的开始
int[][]signal = new int[n][m];//标记连通图包含的点
for(int i = 0;i < n;i++){
for(int j = 0;j < m;j++){
if(start && metric[i][j] == 1) {
signal[i][j] = 1;
metric[i][j] = 2;
ones--;
start = false;
}
else if(metric[i][j] == 1){//如果当前元素为1且左、上两个元素属于连通子图,则当前点是否属于连通子图
if(i > 0 && signal[i - 1][j] == 1) {
signal[i][j] = 1;
metric[i][j] = 2;
ones--;
}
if(j > 0 && signal[i][j - 1] == 1) {
signal[i][j] = 1;
metric[i][j] = 2;
ones--;
}
if(signal[i][j] == 1){//如果当前点属于连通子图,那么其左、上两个元素若为1,也属于连通子图
if(i > 0 && metric[i - 1][j] == 1) {
signal[i - 1][j] = 1;
metric[i - 1][j] = 2;
ones--;
}
if(j > 0 && metric[i][j - 1] == 1) {
signal[i][j - 1] = 1;
metric[i][j - 1] = 2;
ones--;
}
}
}
}
}
return signal;
}
/**
* 计算n行m列的01矩阵的连通子图要变成合法连通子图需要改变的元素数
* 步骤:判断每个元素的行和列上有没有出现过1,
* 如果出现过且与当前的1之间有0,则将之间的0全部变为1,并count++
* @param n
* @param m
* @return count 该01矩阵要变成合法连通矩阵需要改变的元素数
*/
private static int countChanges(int n,int m,int[][]signal){
int count = 0;//记录需要改变的0的个数
int rowSignal = -1;//记录某一行是否有1出现
int[] colSignal = new int[m];//记录某一列是否有1出现
for(int i = 0;i < m;i++)colSignal[i] = -1;//初始化数组
for(int i = 0;i < n;i++){
for(int j = 0;j < m;j++){
if(signal[i][j] == 1){//如果当前数字为1则查看其与同行、同列的其他1之间有没有0,有的话将0变为1,并将count数加1
if((j > (rowSignal + 1)) && (rowSignal != -1)){//对行进行处理
while(++rowSignal < j){//将第i行中两个不相邻1的之间的0全部变为1
signal[i][rowSignal] = 1;
metric[i][rowSignal] = 2;
count++;
}
}
rowSignal = j;
if((i > (colSignal[j] + 1)) && (colSignal[j] != -1)){
while(++(colSignal[j]) < i){//将第j列中两个不相邻的1之间的0全部变为1
signal[colSignal[j]][j] = 1;
metric[colSignal[j]][j] = 2;
count++;
}
}
colSignal[j] = i;
}
}
}
return count;
}
/**
* 判断字符串str是否为数字
* @param str
* @return true/false
*/
public static boolean isNum(String str){
return str.matches("^[-+]?(([0-9]+)([.]([0-9]+))?|([.]([0-9]+))?)$");
}
/**
* 根据行列值从控制台读入01矩阵并得到这个连通矩阵变为合法的需要改变的0的个数
* @param n
* @param m
*/
@SuppressWarnings("resource")
public static int getMetric(int n,int m){
java.util.Scanner sin=new java.util.Scanner(System.in);
int count = 0;//该矩阵需要改变的0的个数
for(int i = 0;i < n;i++){
// String inputStr = scala.Console.readLine();
String inputStr = sin.nextLine();
String[] ss = inputStr.split(" ");
for(int j = 0;j < m;j++){//如果输入不是01矩阵,清空矩阵重新输入
if((!isNum(ss[j])) || (ss.length < m) || ((Integer.parseInt(ss[j]) != 0) && (Integer.parseInt(ss[j]) != 1))){
// System.out.println("请正确输入" + n + "行" + m + "列01矩阵(矩阵只能包含0和1字符,元素间以空格隔开)...");
i = -1;//清空矩阵
break;
}
metric[i][j] = Integer.parseInt(ss[j]);
if(metric[i][j] == 1) ones++;
}
}
while(ones > 0){
count += countChanges(n,m,getConnectedOnes(n,m));
}
return count;
}
@SuppressWarnings("resource")
public static void main(String[]args){
java.util.Scanner sin=new java.util.Scanner(System.in);
//System.out.println("“渣打科营‘Mini Code Marathon’赛题:连通块最少”开始...");
//System.out.println("请输入测试数据:");
int n = 0;
int m = 0;
int[]counts = new int[50];
int index = 0;//第index组测试数据
// String inputStr = scala.Console.readLine();
String inputStr = sin.nextLine();
while(!(inputStr.equals(""))){
String[] ss = inputStr.split(" ");
if(ss.length == 2 && isNum(ss[0]) && isNum(ss[1])) {
n = Integer.parseInt(ss[0]);
m = Integer.parseInt(ss[1]);
if(n > 0 && n <= 50 && m > 0 && m <= 50){
counts[index++] = getMetric(Integer.parseInt(ss[0]),Integer.parseInt(ss[1]));
}else System.out.println("请正确输入01矩阵的行(n)、列(m),(正整数n,m(0<n,m<=50)))...");
}else System.out.println("请正确输入01矩阵的行(n)、列(m),(正整数n,m(0<n,m<=50)))...");
// System.out.println("合法的连通矩阵:");
//
// for(int i = 0;i < n;i++){//输出合法的连通矩阵
//
// for(int j = 0;j < m;j++)
//
// System.out.print(metric[i][j] + " ");
//
// System.out.println();
// }
// System.out.println("请输入下一组测试数据,若要结束,直接回车...");
// inputStr = scala.Console.readLine();
inputStr = sin.nextLine();
}
for(int i = 0;i < index;i++)System.out.println(counts[i]);
}
}
Plus:今天没啥事,就试着写了写,想着各种情况考虑的挺周全的,eclipse/myeclipse运行也都通过了,测试结果没问题,但是提交代码之后,被告知挑战失败,说是可能除数为0导致、、、话说这里好像根本没有乘除运算来者、、、、
罢了,天生没有天外来财的命,失败就失败吧,就是很纠结不知道错在哪里。。。。
挑战 渣打科营“Mini Code Marathon”赛题:连通块最少相关推荐
- 渣打科营 Mini Code Marathon
代码如下,据说格式错误,nnd #include <stdio.h> #include <string.h></
- 渣打科营中心:金融市场的三大挑战
本文讲的是渣打科营中心:金融市场的三大挑战,近日,以"Code to Change --编程美好生活"为主题的首届渣打编程马拉松赛于天津经济技术开发区圆满落幕.本届渣打编程马拉松赛 ...
- 奖iPhone6:渣打银行金融市场软件开发部(中国)“Mini Code Marathon”大赛
一.渣打集团金融市场软件开发中心介绍 渣打集团金融市场软件开发中心是一个全球性机构,为渣打集团金融市场业务提供从设计到实施的IT解决方案.金融市场业务是渣打集团核心金融业务的一部分,通过世界各金融中心 ...
- 首届渣打科营编程马拉松赛初赛圆满结束
本文讲的是首届渣打科营编程马拉松赛初赛圆满结束,首届渣打科营编程马拉松赛初赛于8月31日至9月8日圆满举行,初赛分为天津赛区.北京赛区.上海赛区和成都赛区四场.本届大赛以"Code to C ...
- 2013渣打科营编程马拉松赛 初始题目
/** * 用java编写,写的比较乱,没有体现面向对象,哈哈,结果是对的.欢迎评论! * **/ 题目:https://github.com/aqingsao/length/blob/master ...
- 2013渣打科营编程马拉松赛样题
http://www.scopeinternational.com.cn/codemarathon/samplePractice.action 能打开链接的话,那就看,不能的话,看下面. 由于国内两大 ...
- 渣打科营编程马拉松赛后总结
比赛终于在各种插曲之中结束了,最终获得了一个什么最佳技术创新奖.说兴奋确实挺兴奋的,感谢狗哥和师弟.说遗憾也是挺遗憾的,感觉一开始可以夺冠的,但是之间的一些问题最终变成了这个结果.赛后的回学校的路上, ...
- 记渣打银行科营中心的面试
周六去天津渣打银行科营中心面试,现在来说说自己从这次面试得到的体会. 首先声明:我是一名大四学生,从学校投简历然后经过电话面试,英文电话面试通过了,然后来参加的笔试和面试. 整个面试流程是这样的: 一 ...
- 7.30 正睿暑期集训营 A班训练赛
目录 2018.7.30 正睿暑期集训营 A班训练赛 T1 A.蔡老板分果子(Hash) T2 B.蔡老板送外卖(并查集 最小生成树) T3 C.蔡老板学数学(DP NTT) 考试代码 T2 T3 2 ...
最新文章
- error LNK1112: module machine type 'X86' conflicts with target machine type 'x64'
- mysql 开源 ~ canal+otter系列(2)
- MINIGUI 开发指南---GDI
- 几款不错的VisualStudio2010插件
- RxSwift之深入解析map操作符的底层实现
- c语言水仙花数(输入判断),用c语言判断一个数是否为水仙花数?
- 城市天际线 android,都市天际线安卓手机版
- 使用Context和Hooks来管理状态
- 计算机逻辑学包含分析,逻辑学在职研究生教育的基本内容分析
- 我的第一个keil工具写的汇编
- C语言 第六章 多重循环练习
- pl/mysql安装_PL/SQL环境安装设置
- 数字滤波器及GUI界面的设计(MATLAB)
- Visio网络及设备模板库
- int与byte之间的相互转化
- softmax函数反向传播
- python发送钉钉消息
- 海思Hi3518E MPP学习_02视频输入(VI模块)
- layui 上传图片 返回图片地址
- 印象笔记 HTML邮件,如何通过私有邮箱保存邮件到印象笔记?