有一个9*9的矩阵,每个矩阵单元中随机存储2-5个数字,将1-10这几个数分配到这些单元中,要保证违约分最低,下面是违约分计算方法:相同的单元内出现相同的数字,扣100分,相同的单元内出现相邻的数字,扣50分;相邻的单元内出现相同的数字扣20分,相邻的单元内出现相邻的数字扣除10分(由于判断对象的改变,会重复扣分,比如a【1】【0】和a【1】【1】比较后,扣分,然后a【1】【1】和a【1】【0比较时也会扣分】),求个好一点的思路,有源代码最好

解决方案 »

  1.   

    不是很明白
    单元中随机存储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],所以应该能避免重复吧
      

  2.   

    如果每个单元格放2个的话,每个单元格横坐标x,纵坐标y,第一个元素a[x][y][0]
    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);
      

  3.   

    for example
    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);
        }
    }
      

  4.   

    直接在这里手写的,没运行过,不过思路很清晰了
    看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());
                }
            }
        }
    }
      

  5.   

    还有一个地方
    int times = (int)(Math.random()*4) + 2; //随机数字次数应该是乘4,因为区间是[0,3]