有一个9*9的矩阵,每个矩阵单元中随机存储2-5个数字,将1-10这几个数分配到这些单元中,要保证违约分最低,下面是违约分计算方法:相同的单元内出现相同的数字,扣100分,相同的单元内出现相邻的数字,扣50分;相邻的单元内出现相同的数字扣20分,相邻的单元内出现相邻的数字扣除10分(由于判断对象的改变,会重复扣分,比如a【1】【0】和a【1】【1】比较后,扣分,然后a【1】【1】和a【1】【0比较时也会扣分】),求个好一点的思路,有源代码最好
调试欢乐多
单元中随机存储2-5个数字,是指什么,比如说 a[0][0] = 1,2,3,4,5... 这样?
相邻的判断,只往后方向判断(不判断前方向)应该就可以避免重复判断了吧,比如
比如a[i][j],只判断a[i][j+1],a[i+1][j],而不需要判断a[i][j-1],a[i-1][j],这样,a[i][j+1]判断的时候,就不会再a[i][j],所以应该能避免重复吧
a[x][y][0] = (x * 3 + y * 3) % 10 + 1
a[x][y][1] = (a[x][y][0] == 10) ? 5 : (a[x][y][0] + 5);
import java.util.*;
class UnitData {
List<Integer> data = new ArrayList<Integer>();
public UnitData(List<Integer> list) {
this.data.addAll(list);
} public List<Integer> getData(){
return data;
}
public String toString() {
return data.toString();
}
}public class Test {
public static void main(String[] args) {
UnitData[][] ud = new UnitData[9][9];
List<Integer> asl0 = new ArrayList<Integer>(); //和相邻右,下单元相同的集合
List<Integer> asl1 = new ArrayList<Integer>(); //和相邻右,下单元连续的集合
List<Integer> udl0 = new ArrayList<Integer>(); //当前单元的数字集合
List<Integer> udl1 = new ArrayList<Integer>(); //相邻右方单元的数字集合
List<Integer> udl1 = new ArrayList<Integer>(); //相邻下方单元的数字集合
int same = 0, seq = 0; //相同,连续统计
for (int i=0; i<9; i++) {
for (int j=0; j<9; j++) {
int times = (int)(Math.random()*3) + 2; //随机数字次数
udl0.clear();
for (int k=0; k<times; k++) {
udl0.add((int)(Math.random()*10)+1); //随机数字
}
ud[i][j] = new UnitData(list);
}
} int score = 0; //初始总分
for (int i=0; i<9; i++) {
for (int j=0; j<9; j++) {
udl0.clear();
udl0.addAll(ud[i][j].getData());
Collections.sort(sul0); //排序
same = 0;
seq = 0;
for (int k=1; k<udl0.size(); k++) {
if (udl0.get(k)-udl0.get(k-1) == 1) { //连续
if (seq==0) seq++;
} else if (udl0.get(k)-udl0.get(k-1) == 0) { //相同
if (same==0) same++;
}
}
score -= 100 * same;
score -= 50 * seq;
udl1.clear();
udl2.clear();
if (j<8) { //相邻右单元
udl1.addAll(ud[i][j+1].getData());
Collections.sort(udl1);
}
if (i<8) {//相邻下单元
udl2.addAll(ud[i+1][j].getData());
Collections.sort(udl2);
}
asl0.clear();
asl0.addAll(udl0);
asl0.retainAll(udl1);
asl0.retainAll(udl2); //和右,下方向两个单元格相同的数字,即3个集合的交集 same = 0;
seq = 0;
asl1.clear();
for (int u=0,v=0; u<udl0.size() && v<udl1.size(); ) { //相邻右单元
if (udl0.get(u)-udl1.get(v) == 0) {
if (same==0) same++;
} else if (udl0.get(u)-udl1.get(v) > 0) {
if (udl0.get(u)-udl1.get(v)==1) {
asl1.add(udl1.get(v));
if (seq==0) seq++;
}
v++;
} else if (udl0.get(u)-udl1.get(v) < 0) {
if (udl0.get(u)-udl1.get(v)==-1) {
asl1.add(udl1.get(v));
if (seq==0) seq++;
}
u++;
}
}
score -= 20 * same;
score -= 10 * seq; same = 0;
seq = 0;
for (int u=0,v=0; u<udl0.size() && v<udl2.size(); ) { //相邻下单元
if (udl0.get(u)-udl2.get(v) == 0) {
if (!asl0.contains(udl2.get(v)) && same==0) same++;
} else if (udl0.get(u)-udl2.get(v) > 0) {
if (udl0.get(u)-udl2.get(v)==1) {
if (!asl1.contains(udl2.get(v)) && seq==0) seq++;
}
v++;
} else if (udl0.get(u)-udl2.get(v) < 0) {
if (udl0.get(u)-udl2.get(v)==1) {
if (!asl1.contains(udl2.get(v)) && seq==0) seq++;
}
u++;
}
}
score -= 20 * same;
score -= 10 * same;
}
} System.out.printf("score=%d\n", score);
}
}
看6L的回复,还以为LZ对代码的理解能力应该还不错的,原来LZ还是拿来就用的级别,有待加强啊
把改好的发给你,对比你一下你自己改的,看看你是否真的理解代码了?
(修改的地方很少,关键的修改地方可以说只有一处(注视修改2和修改3的地方),就是计数器忘了递增导致死循环,剩下的修改是一些变量名的错误)import java.util.*;
class UnitData {
List<Integer> data = new ArrayList<Integer>();
public UnitData(List<Integer> list) {
this.data.addAll(list);
} public List<Integer> getData(){
return data;
}
public String toString() {
return data.toString();
}
}public class csdn {
public static void main(String[] args) throws Throwable {
UnitData[][] ud = new UnitData[9][9];
//修改1,把变量名改了,否则太乱
List<Integer> sameList = new ArrayList<Integer>(); //和相邻右,下单元相同的集合
List<Integer> seqList = new ArrayList<Integer>(); //和相邻右,下单元连续的集合
List<Integer> current = new ArrayList<Integer>(); //当前单元的数字集合
List<Integer> right = new ArrayList<Integer>(); //相邻右方单元的数字集合
List<Integer> down = new ArrayList<Integer>(); //相邻下方单元的数字集合
int same = 0, seq = 0; //相同,连续统计
for (int i=0; i<9; i++) {
for (int j=0; j<9; j++) {
int times = (int)(Math.random()*3) + 2; //随机数字次数
current.clear();
for (int k=0; k<times; k++) {
current.add((int)(Math.random()*10)+1); //随机数字
}
ud[i][j] = new UnitData(current);
}
} int score = 0; //初始总分
for (int i=0; i<9; i++) {
for (int j=0; j<9; j++) {
current.clear();
current.addAll(ud[i][j].getData());
Collections.sort(current); //排序
same = 0;
seq = 0;
for (int k=1; k<current.size(); k++) {
if (current.get(k)-current.get(k-1) == 1) { //连续
if (seq==0) seq++;
} else if (current.get(k)-current.get(k-1) == 0) { //相同
if (same==0) same++;
}
}
score -= 100 * same;
score -= 50 * seq;
right.clear();
down.clear();
if (j<8) { //相邻右单元
right.addAll(ud[i][j+1].getData());
Collections.sort(right);
}
if (i<8) {//相邻下单元
down.addAll(ud[i+1][j].getData());
Collections.sort(down);
}
sameList.clear();
sameList.addAll(current);
sameList.retainAll(right);
sameList.retainAll(down); //和右,下方向两个单元格相同的数字,即3个集合的交集 same = 0;
seq = 0;
seqList.clear();
for (int u=0,v=0; u<current.size() && v<right.size(); ) { //相邻右单元
if (current.get(u)-right.get(v) == 0) {
if (same==0) same++;
u++; //修改2 计数器没递增,所以导致死循环
v++;
} else if (current.get(u)-right.get(v) > 0) {
if (current.get(u)-right.get(v)==1) {
seqList.add(right.get(v));
if (seq==0) seq++;
}
v++;
} else if (current.get(u)-right.get(v) < 0) {
if (current.get(u)-right.get(v)==-1) {
seqList.add(right.get(v));
if (seq==0) seq++;
}
u++;
}
}
score -= 20 * same;
score -= 10 * seq; same = 0;
seq = 0;
for (int u=0,v=0; u<current.size() && v<down.size(); ) { //相邻下单元
if (current.get(u)-down.get(v) == 0) {
if (!sameList.contains(down.get(v)) && same==0) same++;
u++; //修改3,和修改2一样
v++;
} else if (current.get(u)-down.get(v) > 0) {
if (current.get(u)-down.get(v)==1) {
if (!seqList.contains(down.get(v)) && seq==0) seq++;
}
v++;
} else if (current.get(u)-down.get(v) < 0) {
if (current.get(u)-down.get(v)==-1) {
if (!seqList.contains(down.get(v)) && seq==0) seq++;
}
u++;
}
}
score -= 20 * same;
score -= 10 * same; }
} System.out.printf("score=%d\n", score);
for (int i=0; i<9; i++) { //追加单元的打印,方便检查分数是否正确
for (int j=0; j<9; j++) {
System.out.printf("row=%d, col=%d, data=%s\n", i, j, ud[i][j].toString());
}
}
}
}
int times = (int)(Math.random()*4) + 2; //随机数字次数应该是乘4,因为区间是[0,3]