hnustoj 1030: Count the Number of Cycles

题目描述

In information theory, a low-density parity-check (LDPC) code is a linear error correcting code, a method of transmitting a message over a noisy transmission channel, and is constructed using a sparse bipartite graph. LDPC codes are capacity-approaching codes, which means that practical constructions exist that allow the noise threshold to be set very close (or even arbitrarily close on the BEC) to the theoretical maximum (the Shannon limit) for a symmetric memory-less channel.
LDPC codes are defined by a sparse parity-check matrix. This parity-check matrix is often randomly generated and the elements in it are 0 or 1. If we want use LDPC codes, we should make the parity-check matrix have no cycles. When four vertices of the rectangle in the matrix are 1, we say that the matrix has one cycle. Now we want to know how many cycles are in the matrix.
For a given matrix, you are to count the number of cycles in the matrix.

输入

There are several test cases, each test case starts with a line containing two positive integers M and N. M and N is the size of the matrix (1<=M<=100, 1<=N<=100). Next follow a matrix which contains only number 0 and 1. The input will finish with the end of file.

输出

.   For each the case, your program will output the number of cycles in the given matrix on separate line.

样例输入

1 3
1 1 1
2 3
1 0 1
0 1 1
3 3
1 0 1
0 1 1
1 1 1

样例输出

0
0
2

题意:如果一个01矩阵中有任何4个1分别在矩形的4个顶点上,则这4个1构成一个


四环。

给你一个大小为M×N的01矩阵,你需要求出矩阵中四环的数目。

本题是一道简单思维题,主要考核参赛选手的思维能力


暴力穷举,时间复杂度为n^4,会超时

分析知,将矩阵的2行进行向量点乘,如果结果s小于2,说明这2行不存在四环,


如果结果s大于等于2,则这2行的四环数目为C(2,S)

所以此题可以将各行两两一组进行点乘,然后将各组四环数目相加,即得到最后


答案。

复杂度为n^3。


话不多说,上AC代码

#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 101;
int mat[maxn][maxn];
int c[maxn+10];

void init(){
	for(int i = 2; i < maxn; i++)
		c[i] = (i-1)*i/2;
}
int calc(int *a, int *b, int num){
	int sum = 0;
	for(int i = 0; i < num; i++){
		sum += a[i]*b[i];
	}
	if(sum < 2) return 0;
	else return c[sum];
}
int main(){
	int a, b;
	init();
	while(cin >> a>> b){
		int cnt = 0;
		if(a == 1) {
			for(int i = 0; i < a; i++)
			for(int j = 0; j < b; j++)
			scanf("%d", &mat[i][j]);
			cout << 0 <<endl;
			continue;
		}
		for(int i = 0; i < a; i++)
		for(int j = 0; j < b; j++)
			scanf("%d", &mat[i][j]);
		for(int i = 0 ; i < a-1; i++){
			for(int j = i+1; j < a; j++){
				cnt+=calc(mat[i], mat[j], b);
			}
		}
		cout << cnt <<endl;
	}
	
	return 0; 
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值