前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【kAriOJ】离散数学 构造群码 极大似然法解码

【kAriOJ】离散数学 构造群码 极大似然法解码

作者头像
饶文津
发布2020-06-02 11:03:39
5140
发布2020-06-02 11:03:39
举报
文章被收录于专栏:饶文津的专栏

A. 编程题1 构造群码

时间限制 1000 ms 内存限制 65536 KB

题目描述

针对给定H,计算群码编码函数eH,并计算给定字的码字。

输入格式

第一行输入两个整数m,n;(m < n ,n < 10)

第二行输入m × (n - m) 个0或1,也就是矩阵H的上半部分,下半部分单位矩阵自行生成;

第三行输入m比特的字;

输出格式

第一行输出该编码函数能检测到的错误位数;

第二行输出给定字的码字;

输入样例

代码语言:javascript
复制
2 5
1 1 0 0 1 1
1 1

输出样例

代码语言:javascript
复制
2
11101

能检测到的错误位数,就是0~2^m-1生成的编码和0的非零距离的最小值-1。

编码就直接乘上[I|H],有个地方害我一直wa的,就是int k=0; if(g&(1<<j))k=1; bn[i]^=k&h[m-j][i];我写成了 bn[i]^=g&(1<<j)&h[m-j][i];

代码语言:javascript
复制
/*
TASK:构造群码
LANG:C++
URL:http://code.bupt.edu.cn/problem/contest/491/problem/A/
*/
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define N 30
#define ll long long
using namespace std;
int n,m,h[N][N];
int bm[N],bn[N];
//计算n长度的a的权
int weight(int *a){
    int ans=0;
    for(int i=1;i<=n;i++)
        ans+=a[i];
    return ans;
}
//计算最多检测的错误
int getk(){
    int ans=100;
    //g的二进制即生成的Bm
    for(ll g=1;g<1<<m;g++){
        memset(bn,0,sizeof bn);
        for(int i=1;i<=n;i++)
            for(int j=m-1;j>=0;j--){
                int k=0;
                if(g&(1<<j))k=1;
                bn[i]^=k&h[m-j][i];
            }
        int w=weight(bn);
        if(w)ans=min(ans,weight(bn));
    }
    return ans-1;
}
int main() {
    scanf("%d%d",&m,&n);
    for(int i=1;i<=m;i++){
        for(int j=m+1;j<=n;j++)
            scanf("%d",&h[i][j]);
        h[i][i]=1;
    }
    printf("%d\n",getk());
     
    for(int i=1;i<=m;i++)
        scanf("%d",&bm[i]);
    //将bm编码成bn
    for(int i=1;i<=n;i++){
        bn[i]=0;
        for(int j=1;j<=m;j++)
            bn[i]^=bm[j]&h[j][i];
    }
    for(int i=1;i<=n;i++)printf("%d",bn[i]);
     
    return 0;
}

A. 编程题2 极大似然法解码

时间限制 1000 ms 内存限制 65536 KB

题目描述

给定群码(m,n)的编码函数e的H,采用极大似然法进行解码 (n<=20)

输入格式

第一行输入两个整数m,n;

第二行输入m × (n - m) 个0或1,也就是矩阵H的上半部分,下半部分单位矩阵自行生成;

第三行输入n比特的字;

输出格式

第一行:输出与e相关的极大似然法能纠错的比特数

第二行:采用极大似然法对给定的字解码后的字

输入样例

代码语言:javascript
复制
3 6
1 1 0 1 0 1 0 1 1
001110

输出样例

代码语言:javascript
复制
1
011

在所有编码和0的距离时,把编出来的码记录起来,然后解码时遍历所有编码,找到距离最近的,就是答案了。

代码语言:javascript
复制
/*
TASK:极大似然法解码
LANG:C++
URL:http://code.bupt.edu.cn/problem/contest/492/problem/A/
*/
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define N 50
#define ll long long
using namespace std;
int n,m,h[N][N];
int bm[N];
ll bn[2000][N];
int tmp[N];
//计算n长度的a的权
int weight(ll a[N]){
    int ans=0;
    for(int i=1;i<=n;i++)
        ans+=a[i];
    return ans;
}
//计算最多检测的错误,同时计算得到所有的对应编码
int getk(){
    int ans=100;
    //g的二进制即生成的Bm
    for(ll g=1;g<1<<m;g++){
        for(int i=1;i<=n;i++)
            for(int j=m-1;j>=0;j--){
                int k=0;
                if(g&(1<<j))k=1;
                bn[g][i]^=k&h[m-j][i];
            }
        int w=weight(bn[g]);
        if(w)ans=min(ans,w);
    }
    return (ans-1)/2;
}
int getn(){
    int mi=100,ans=0;
    for(ll g=0;g<1<<m;g++){
        int dif=0;
        for(int i=1;i<=n;i++){
            if(bn[g][i]!=tmp[i])dif++;
        }
        if(mi>dif){
            mi=dif;
            ans=g;
        }
    }
    return ans;
}
int main() {
    scanf("%d%d",&m,&n);
    for(int i=1;i<=m;i++){
        for(int j=m+1;j<=n;j++)
            scanf("%d",&h[i][j]);
        h[i][i]=1;
    }
    printf("%d\n",getk());
     
    for(int i=1;i<=n;i++){
        char c;
        scanf(" %c",&c);
        tmp[i]=c-'0';
    }
    int ans=getn();
    for(int i=m-1;i>=0;i--)
        printf("%d",(1<<i)&ans?1:0);
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-11-03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • A. 编程题1 构造群码
  • 题目描述
  • 输入格式
  • 输出格式
  • 输入样例
  • 输出样例
  • A. 编程题2 极大似然法解码
    • 题目描述
      • 输入格式
        • 输出格式
          • 输入样例
            • 输出样例
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档