关注
感觉他们的数据量应该特别的小......我最后一题直接暴力模拟竟然过了(N多重嵌套循环)... 2的 package WY;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/**
* 思路:
* 1. 暴力生成6个字母的全部排列试一下?
*/
public class wangyi02 {
public static void main(String[] args){
wangyi02 wangyi02 = new wangyi02();
wangyi02.Input();
}
int T;
String str;
String[] array = {
"A","S","D","F","G","H"
};
String[] finalResult = new String[6];
// 用于表示某个字母目前在哪个位置
Map<String,Integer> finalMapping = new HashMap<>();
boolean[] visited = new boolean[6];
// 最小代价
int minReuslt = Integer.MAX_VALUE;
public void Input(){
Scanner in = new Scanner(System.in);
T = in.nextInt();
for(int i=0;i<T;i++){
str = in.next();
minReuslt = Integer.MAX_VALUE;
DFS(0);
System.out.println(minReuslt);
}
}
public void DFS(int index){
if(index==6){
// finalResult是最终生成的排列
Compute();
return;
}
for(int i=0;i<array.length;i++){
if(!visited[i]){
visited[i] = true;
finalResult[index] = array[i];
finalMapping.put(array[i],index);
DFS(index+1);
visited[i] = false;
}
}
}
public void Compute(){
// 记录当前手放在哪个位置上
int nowIndex = 0;
// 代价
int result = 0;
for(int i=0;i<str.length();i++){
String ch = str.charAt(i)+"";
result += Math.abs(nowIndex - finalMapping.get(ch));
nowIndex = finalMapping.get(ch);
}
if(result<minReuslt){
minReuslt = result;
}
}
} 3的 package WY;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.Scanner;
/**
* 思路:
* 1. 对着题意模拟.
* 坑:
* 1. 数量最多指的不是在整个游戏里数量最多,是指联通数量最多.
* 举例:
* 131
* 331
* 这里3的联通数量最多,因为1的联通数量最大是2,3是3
*/
public class wangyi03 {
public static void main(String[] args){
wangyi03 wangyi03 = new wangyi03();
wangyi03.Input();
}
int T;
int M,N;
char[][] array;
// 当前要消除的方块的具***置
int nowRemoveI,nowRemoveJ;
public void Input(){
Scanner in = new Scanner(System.in);
T = in.nextInt();
for(int i=0;i<T;i++){
M = in.nextInt();
N = in.nextInt();
array = new char[M][N];
for(int j=0;j<M;j++){
array[j] = in.next().toCharArray();
}
// 重置所有状态后进行计算
nowRemoveI = 0;
nowRemoveJ = 0;
DFScount = 0;
Slove();
}
}
public void Slove(){
while (nowRemoveI!=-1 && nowRemoveJ!=-1) {
// 第一步,找到要进行消除的方块
// 规则:
// 1. 数量最多; 2. 编号最小; 3. 行最小,列最小;
GetRemoveIndex();
if(nowRemoveI==-1 && nowRemoveJ==-1) break;
// 第二步,消除目标方块,并且应用规则重排整个数组(所有已空位置设为'#')
Remove();
// 每完成一步输出一下
// Print();
// System.out.println();
}
int c = 0;
// 第三步,找到剩余格子数量并输出
for(int i=0;i<M;i++)
for(int j=0;j<N;j++)
if(array[i][j]!='#') c++;
System.out.println(c);
}
int DFScount = 0;
int[][] dir = new int[][]{
{1,0}, // 下
{0,1}, // 右
{-1,0}, // 上
{0,-1} // 左
};
public void DFS(int x,int y,char target,boolean[][] visited){
// 不搜空的地方
if(target=='#') return;
for(int i=0;i<4;i++){
int tempX = x+dir[i][0];
int tempY = y+dir[i][1];
if(tempX>=0&&tempX<M&&tempY>=0&&tempY<N && !visited[tempX][tempY] && array[tempX][tempY]==target){
visited[tempX][tempY] = true;
DFScount ++;
DFS(tempX,tempY,target,visited);
}
}
}
// DFS找到联通数量最多的方块
public void FindMaxCount(int[] count){
boolean[][] visited = new boolean[M][N];
for(int i=0;i<M;i++){
for(int j=0;j<N;j++){
if(!visited[i][j] && array[i][j]!='#'){
DFScount = 1;
visited[i][j] = true;
DFS(i,j,array[i][j],visited);
if(DFScount>count[array[i][j]-'0']){
count[array[i][j]-'0'] = DFScount;
}
}
}
}
}
public void GetRemoveIndex(){
// 首先找数量最多的
int maxCount = 0;
// count[i]表示第i个数字的最大联通数量
int[] count = new int[10];
FindMaxCount(count);
for(int i=0;i<10;i++) maxCount = Math.max(maxCount,count[i]);
if(maxCount == 1 || maxCount==0){
// 最大数量为1的时候,说明已经没有方块可以消除了
nowRemoveI = -1;
nowRemoveJ = -1;
return;
}
char minIndex = 0;
// 找到数量最多之中的编号最小的
for(int i=0;i<10;i++){
if(count[i]==maxCount){
minIndex = (char)(i+'0');
break;
}
}
boolean[][] visited = new boolean[M][N];
// 找到编号最小的之中行最小,列最小的(还得是数量最多的)
for(int i=0;i<M;i++){
for(int j=0;j<N;j++){
if(array[i][j]==minIndex && !visited[i][j]) {
visited[i][j] = true;
DFScount = 1;
DFS(i, j,minIndex,visited);
if(DFScount == maxCount){
nowRemoveI = i;
nowRemoveJ = j;
return;
}
}
}
}
}
public void DFSRemove(int x,int y,char target,boolean[][] visited){
// 不搜空的地方
if(target=='#') return;
array[x][y] = '#';
for(int i=0;i<4;i++){
int tempX = x+dir[i][0];
int tempY = y+dir[i][1];
if(tempX>=0&&tempX<M&&tempY>=0&&tempY<N && !visited[tempX][tempY] && array[tempX][tempY]==target){
visited[tempX][tempY] = true;
DFSRemove(tempX,tempY,target,visited);
}
}
}
public void Remove(){
boolean[][] visited = new boolean[M][N];
DFSRemove(nowRemoveI,nowRemoveJ,array[nowRemoveI][nowRemoveJ],visited);
// 重排数组,只要一列中#上方的不是#,那么就继续重排
for(int j=0;j<N;j++){
while (true) {
boolean isBreak = true;
for (int i = 0; i < M; i++) {
// 如果下面的格子为空,那么将它与它下面的格子交换
int bottom = i+1;
if(bottom<M && array[bottom][j]=='#'){
array[bottom][j] = array[i][j];
array[i][j] = '#';
}
}
for(int i=0;i<M;i++){
// 只要#上方不是#,就继续重排
int top = i-1;
if(top>=0 && array[i][j]=='#' && array[top][j]!='#') {
isBreak = false;
break;
}
}
if(isBreak) break;
}
}
// for(int i=0;i<M;i++){
// for(int j=0;j<N;j++){
// // 如果下面的格子为空,那么将它与它下面的格子交换
// int bottom = i+1;
// if(bottom<M && array[bottom][j]=='#'){
// array[bottom][j] = array[i][j];
// array[i][j] = '#';
// }
// }
// }
// 第一列为空的情况下,不停的运行这段代码
while (true) {
// 第一列空格子数量
int oneColEmpty = 0;
// 是否整个数组都为空
boolean isEmpty = true;
// 如果某一列为空,那么将其右边的一列来取代他
for (int j = 0; j < N; j++) {
// 该列空格子数
int colEmpty = 0;
for (int i = M - 1; i >= 0; i--) {
if (array[i][j] == '#') colEmpty++;
if(array[i][j]=='#' && j==0) oneColEmpty++;
}
int right = j + 1;
// 空格子数==M表示该列为空,那么让其右边的一列取代他
if (colEmpty == M && right < N) {
for (int i = 0; i < M; i++) {
array[i][j] = array[i][right];
array[i][right] = '#';
}
}
if(colEmpty!=M) isEmpty = false;
}
if(oneColEmpty!=M) break;
// 整个数组为空的情况下也结束循环
if(isEmpty) break;
}
}
public void Print(){
for(int i=0;i<M;i++){
for(int j=0;j<N;j++){
System.out.print(array[i][j]);
}
System.out.println();
}
}
}
代码写的比较烂....因为时间比较赶...献丑了5555
查看原帖
点赞 3
相关推荐
12-17 13:33
吉林大学 Java
求一个offer_T...:哥我太懂你了 点赞 评论 收藏
分享
11-19 17:27
门头沟学院 嵌入式软件开发 点赞 评论 收藏
分享
程序员花海_:实习写的看起来像项目了
点赞 评论 收藏
分享
牛客热帖
更多
正在热议
更多
# 2025年终总结 #
147139次浏览 2514人参与
# 秋招落幕,你是He or Be #
3147次浏览 76人参与
# 应届生进小公司有什么影响吗 #
109043次浏览 1116人参与
# 比亚迪工作体验 #
70074次浏览 254人参与
# 你面试体验感最差/最好的公司 #
2973次浏览 56人参与
# 工作中听到最受打击的一句话 #
2482次浏览 61人参与
# 大厂VS公务员你怎么选 #
71096次浏览 660人参与
# 重来一次,你会对开始求职的自己说 #
2909次浏览 71人参与
# 一人说一个提前实习的好处 #
3288次浏览 70人参与
# 团建是“福利”还是是 “渡劫” #
3978次浏览 110人参与
# 实习没事做是福还是祸? #
8170次浏览 135人参与
# 如何排解工作中的焦虑 #
243722次浏览 2241人参与
# 从顶到拉给所有面过的公司评分 #
144784次浏览 518人参与
# 今年你最想重开的一场面试是? #
1375次浏览 25人参与
# 你小心翼翼的闯过多大的祸? #
6872次浏览 109人参与
# 联影求职进展汇总 #
123816次浏览 781人参与
# OPPO求职进展汇总 #
755874次浏览 5390人参与
# 互联网公司爆料 #
158562次浏览 724人参与
# 产品实习,你更倾向大公司or小公司 #
189081次浏览 2053人参与
# 秋招结束之后的日子 #
113894次浏览 1038人参与

