标签:
小明陪小红去看钻石,他们从一堆钻石中随机抽取两颗并比较她们的重量。这些钻石的重量各不相同。在他们们比较了一段时间后,它们看中了两颗钻石g1和g2。现在请你根据之前比较的信息判断这两颗钻石的哪颗更重。
给定两颗钻石的编号g1,g2,编号从1开始,同时给定关系数组vector,其中元素为一些二元组,第一个元素为一次比较中较重的钻石的编号,第二个元素为较轻的钻石的编号。最后给定之前的比较次数n。请返回这两颗钻石的关系,若g1更重返回1,g2更重返回-1,无法判断返回0。输入数据保证合法,不会有矛盾情况出现。
2,3,[[1,2],[2,4],[1,3],[4,3]],4
返回: 1
注意,这里面考查的知识点和细节。分析如下:
g1和g2这两块钻石,如果有关系可以是直接的联系,也可以是通过其他钻石的比较而得出的。我的第一个思路:
1.g1和g2直接相连,g1在前返回1,g2在前返回-1;
2.g1和g2间接相连,那么g1、g2能够比较的情况是固定g1,g2比(比g1重的)还重;g2比(比g1轻的)还轻
有了这个关系,我就只用遍历关系矩阵,第一种情况的判断可以直接来,第二种情况其实就是搜集比g1重的和比g1轻的两个集合。判断g2在不在这两个集合中。我试了下这个,可以通过31%的case。当时觉得我这样没什么问题,现在提笔一写发现,我的思想有纰漏。我计算了g1,比g1重的,比g1轻的。然后拿g2来与g1的关系比较。所以问题是g1与g2的关系却未曾比较。
下面看一下第二个思路:
g1与g2之间的关系其实是张图,那么我们就要把图表示出来。如果g1与g2直接相连,那么就是直接比较。我们选用邻接矩阵表示图。那么map[g1][g2]=1就表示g1比g2重。那么问题来了?怎样初始化邻接矩阵?g1,g2邻接我们知道map[g1][g2]=1。但是不邻接并不代表map[g1][g2]的值是好多。初始化邻接矩阵步骤如下:
a.求得矩阵的维数。这个要根据关系矩阵中最大的那个值设置。
b.初始化元素值。对角线因为是自身连通,故初始化为1,其他初始化为0。
c.根据关系矩阵初始化邻接矩阵。(直接初始化)
d.还需要间接初始化。这个意思就是map[i][j]可能通过节点k连通,从而map[i][j]=1。
这下问题解决一大半。我们只用看map[i][j]是否为1或者map[j][i]是否为1即可判断两者是否连接。这样问题就自然解决了。代码如下:
int cmp(int g1, int g2, vector<vector<int> > records, int n) { // write code here int maxNum=-99999; for(int i=0;i<n;i++) { maxNum=maxNum>records[i][0]?maxNum:records[i][0]; maxNum=maxNum>records[i][1]?maxNum:records[i][1]; } int map1[maxNum+1][maxNum+1]; for(int i=0;i<=maxNum;i++) for(int j=0;j<=maxNum;j++) if(i==j)map1[i][j]=1; else map1[i][j]=0; for(int i=0;i<n;i++) map1[records[i][0]][records[i][1]]=1; for(int k=0;k<=maxNum;k++) for(int i=0;i<=maxNum;i++) for(int j=0;j<=maxNum;j++) if(map1[i][k]&&map1[k][j]) map1[i][j]=1; if(map1[g1][g2])return 1; else if(map1[g2][g1])return -1; return 0; }
DEV-C++使用的编译器是GCC,它允许使用变量作为数组的长度定义数组。
VC的编译器不是GCC,它不允许你这样做。
方法1:使用动态内存分配,new和delete操作符
int num;
cin >> num;
int* a = new int[num];
delete[] a;
方法2:使用vector容器
int num;
cin >> num;
vector a(num);
注意:在为数组分配内存失败的时候,以上两种方法均会抛出异常bad_alloc
之后我会总结图的题目和解题方法。
标签:
原文地址:http://blog.csdn.net/yutianxin123/article/details/52083484