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”赛题:连通块最少相关推荐

  1. 渣打科营 Mini Code Marathon

    代码如下,据说格式错误,nnd #include <stdio.h> #include <string.h></

  2. 渣打科营中心:金融市场的三大挑战

    本文讲的是渣打科营中心:金融市场的三大挑战,近日,以"Code to Change --编程美好生活"为主题的首届渣打编程马拉松赛于天津经济技术开发区圆满落幕.本届渣打编程马拉松赛 ...

  3. 奖iPhone6:渣打银行金融市场软件开发部(中国)“Mini Code Marathon”大赛

    一.渣打集团金融市场软件开发中心介绍 渣打集团金融市场软件开发中心是一个全球性机构,为渣打集团金融市场业务提供从设计到实施的IT解决方案.金融市场业务是渣打集团核心金融业务的一部分,通过世界各金融中心 ...

  4. 首届渣打科营编程马拉松赛初赛圆满结束

    本文讲的是首届渣打科营编程马拉松赛初赛圆满结束,首届渣打科营编程马拉松赛初赛于8月31日至9月8日圆满举行,初赛分为天津赛区.北京赛区.上海赛区和成都赛区四场.本届大赛以"Code to C ...

  5. 2013渣打科营编程马拉松赛 初始题目

    /** * 用java编写,写的比较乱,没有体现面向对象,哈哈,结果是对的.欢迎评论! * **/ 题目:https://github.com/aqingsao/length/blob/master ...

  6. 2013渣打科营编程马拉松赛样题

    http://www.scopeinternational.com.cn/codemarathon/samplePractice.action 能打开链接的话,那就看,不能的话,看下面. 由于国内两大 ...

  7. 渣打科营编程马拉松赛后总结

    比赛终于在各种插曲之中结束了,最终获得了一个什么最佳技术创新奖.说兴奋确实挺兴奋的,感谢狗哥和师弟.说遗憾也是挺遗憾的,感觉一开始可以夺冠的,但是之间的一些问题最终变成了这个结果.赛后的回学校的路上, ...

  8. 记渣打银行科营中心的面试

    周六去天津渣打银行科营中心面试,现在来说说自己从这次面试得到的体会. 首先声明:我是一名大四学生,从学校投简历然后经过电话面试,英文电话面试通过了,然后来参加的笔试和面试. 整个面试流程是这样的: 一 ...

  9. 7.30 正睿暑期集训营 A班训练赛

    目录 2018.7.30 正睿暑期集训营 A班训练赛 T1 A.蔡老板分果子(Hash) T2 B.蔡老板送外卖(并查集 最小生成树) T3 C.蔡老板学数学(DP NTT) 考试代码 T2 T3 2 ...

最新文章

  1. error LNK1112: module machine type 'X86' conflicts with target machine type 'x64'
  2. mysql 开源 ~ canal+otter系列(2)
  3. MINIGUI 开发指南---GDI
  4. 几款不错的VisualStudio2010插件
  5. RxSwift之深入解析map操作符的底层实现
  6. c语言水仙花数(输入判断),用c语言判断一个数是否为水仙花数?
  7. 城市天际线 android,都市天际线安卓手机版
  8. 使用Context和Hooks来管理状态
  9. 计算机逻辑学包含分析,逻辑学在职研究生教育的基本内容分析
  10. 我的第一个keil工具写的汇编
  11. C语言 第六章 多重循环练习
  12. pl/mysql安装_PL/SQL环境安装设置
  13. 数字滤波器及GUI界面的设计(MATLAB)
  14. Visio网络及设备模板库
  15. int与byte之间的相互转化
  16. softmax函数反向传播
  17. python发送钉钉消息
  18. 海思Hi3518E MPP学习_02视频输入(VI模块)
  19. layui 上传图片 返回图片地址
  20. 印象笔记 HTML邮件,如何通过私有邮箱保存邮件到印象笔记?

热门文章

  1. ensp模拟企业网络
  2. 无线协商速率计算原理
  3. Oracle OMF(Oracle Managed Files ) 说明
  4. 蓝城兄弟Q4业绩背后,垂直社区具备多少想象力?
  5. jquery常用知识
  6. CSS设置table下tbody的滚动条
  7. 程序人生 | C语言字节对齐问题详解 - 对齐/字节序/位序/网络序等(上)
  8. 图像正投影与重建初认识
  9. 选择SOLIDEDGE的10大理由(2)
  10. docker从零开始(四)集群初体验,docker-machine swarm