Description
未名湖附近共有N个大小湖泊L1, L2, ..., Ln(其中包括未名湖),每个湖泊Li里住着一只青蛙Fi(1 ≤ i≤ N)。如果湖泊Li和Lj之间有水路相连,则青蛙Fi和Fj互称为邻居。现在已知每只青蛙的邻居数目x1, x2, ..., xn,请你给出每两个湖泊之间的相连关系。
Input
第一行是测试数据的组数T(0 ≤ T≤ 20)。每组数据包括两行,第一行是整数N(2 < N< 10),第二行是N个整数,x1, x2,..., xn(0 ≤ xi≤ N)。
Output
对输入的每组测试数据,如果不存在可能的相连关系,输出"NO"。否则输出"YES",并用N×N的矩阵表示湖泊间的相邻关系,即如果湖泊i与湖泊j之间有水路相连,则第i行的第j个数字为1,否则为0。每两个数字之间输出一个空格。如果存在多种可能,只需给出一种符合条件的情形。相邻两组测试数据之间输出一个空行。
Sample Input
3
7
4 3 1 5 4 2 1
6
4 3 1 4 2 0
6
2 3 1 1 2 1
Sample Output
YES
0 1 0 1 1 0 1
1 0 0 1 1 0 0
0 0 0 1 0 0 0
1 1 1 0 1 1 0
1 1 0 1 0 1 0
0 0 0 1 1 0 0
1 0 0 0 0 0 0
NO
YES
0 1 0 0 1 0
1 0 0 1 1 0
0 0 0 0 0 1
0 1 0 0 0 0
1 1 0 0 0 0
0 0 1 0 0 0
要求:判断序列是否可图——可根据havel算法
havel算法:将递减序列 首元素个后面的元素相应减一,再次排列。如果最终次序列可以全部为零,则该序列可以是可图的。否则不可图。
理解的不难 但是在写的时候,发现自己可能又要用三重循环实现。而且条件很多,我一般不会让自己取用判断条件很多的情况,会把自己绕进去。
后来我学历了网上的代码。作者提前找到了排序序列区间的规律 ,因此可以利用双重循环实现。
而且在二重循环的次数中利用当前序列最大值的个数 控制的。
学习代码:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
struct Point{
int index;
int weight;
};
int tag[200][200];
struct Point map[20];
bool cmp ( Point a, Point b){
return a.weight > b.weight;
}
int main(){
int t,n,flag ;
cin >>t;
while(t--){
cin >> n ;
flag = 1;
memset(tag,0,sizeof(tag));
for(int i =0 ; i <n;++i){
cin >> map[i].weight;
map[i].index = i ;//
}
for(int i = 0; i < n ;++i){
sort(map+i,map+n,cmp);//
if(map[n-1].weight < 0){//排序之后最小的在后面,因此总是判断最后一个是否为负数
flag = 0;
break;
}
if(map[i].weight==0){//
break;//结点都是零的状态
}
else {
for(int j = i+1 ; map[i].weight > 0; ++j){ //
map[i].weight--;//
map[j].weight--;
tag[map[i].index][map[j].index] = 1;//对于邻接矩阵的存储我是靠记忆的
tag[map[j].index][map[i].index] = 1;
}
}
}
if(flag){
cout << "Yes"<<endl;
for(int i =0 ; i< n ;++i){
for (int j= 0; j < n ;++j){
if(j==0){
cout <<tag[i][j];
}
else {
cout <<" "<<tag[i][j];
}
}
cout << endl;
}
}
else {
cout <<"No"<<endl;
}
}
return 0;
}
for(int i = 0; i < n ;++i){
sort(map+i,map+n,cmp);//
if(map[n-1].weight < 0){//排序之后最小的在后面,因此总是判断最后一个是否为负数
flag = 0;
break;
}
if(map[i].weight==0){//
break;//结点都是零的状态
}
else {
for(int j = i+1 ; map[i].weight > 0; ++j){ //
map[i].weight--;//
map[j].weight--;
tag[map[i].index][map[j].index] = 1;
tag[map[j].index][map[i].index] = 1;
}
}
}
我认为以上是核心代码部分,一重循环中要对最后一个元素进行判断是否负数,我在想会不会遗漏呢?后来想进行排序,那最小的会在后面。
另外一点是,当当前结点也就是最大值是零的状态 就代表判断结束 则是可图的