IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> CSP202112——T3登机牌条码 -> 正文阅读

[C++知识库]CSP202112——T3登机牌条码

其实题目已经给了模拟思路了:

  1. 计算数据码字、填充码字和长度码字(注意特判s==-1的时候)
  2. 计算校验码字,主要是一个多项式求余

数据码字

  1. 按题意模拟,解析字符串,得到编码值,如果长度是奇数就在加个29
  2. 两两合并
  3. 增加填充码字(使得总个数%w==0)
  4. 增加长度码字

校验码字

  1. 这题难点就在怎么多项式求余,还好数据比较松可以O(N^2)模拟竖式除法
  2. 需要用一个多项式乘法求出gx的系数(求的过程中模929,否则会爆)
  3. fx/gx多项式除法,用一个vector记录对应位置的系数
  4. 注意除法余项的系数取反 ,因为题目给的-rx
/*
 * @Email: zhiyyyu@gmail.com
 * @Author: Deng Zehui
 * @Github: nArrow4
 * @Date: 2022-02-23 10:10:43
 */
#include<bits/stdc++.h>
using namespace std;
typedef int Module;
typedef enum{
    UPPER,
    LOWER,
    DIGIT,
} MODE;

vector<Module> modules, g, rx;
int w, s;
int n, k;
const int MOD = 929;
string text;

void getModules(const string& t){
    MODE m = UPPER;
    int n = t.size();
    for (int i = 0; i < n;i++){
        switch(m){
        case UPPER:
            if(islower(t[i])){
                modules.push_back(27);
                modules.push_back(t[i] - 'a');
                m = LOWER;
            } else if(isdigit(t[i])){
                modules.push_back(28);
                modules.push_back(t[i] - '0');
                m = DIGIT;
            } else{
                modules.push_back(t[i] - 'A');
            }
            break;
        case LOWER:            
            if(isupper(t[i])){
                modules.push_back(28);
                modules.push_back(28);
                modules.push_back(t[i] - 'A');
                m = UPPER;
            } else if(isdigit(t[i])){
                modules.push_back(28);
                modules.push_back(t[i] - '0');
                m = DIGIT;
            } else{
                modules.push_back(t[i] - 'a');
            }
            break;
        case DIGIT:
            if(isupper(t[i])){
                modules.push_back(28);
                modules.push_back(t[i] - 'A');
                m = UPPER;
            } else if(islower(t[i])){
                modules.push_back(27);
                modules.push_back(t[i] - 'a');
                m = LOWER;
            } else{
                modules.push_back(t[i] - '0');
            }
            break;
        }
    }
    int size = modules.size();
    if(size&1){
        modules.push_back(29);
        size++;
    }
    for (int i = 0; i < size;i+=2){
        int j = i / 2;
        modules[j] = modules[i] * 30 + modules[i + 1];
    }
    modules.resize(size / 2);

    n = modules.size() + 1;
    k = pow(2, s + 1);
    if(s == -1){
        if(n % w){
            int fill = w - n % w;
            n += fill;
            for (int i = 0; i < fill;i++){
                modules.push_back(900);
            }
        }
    } else{
        if((n + k) % w){
            int fill = w - (n + k) % w;
            n += fill;
            for (int i = 0; i < fill;i++){
                modules.push_back(900);
            }
        }
    }
    modules.insert(modules.begin(), n);
}

// 多项式乘法计算g的系数
// 一项一项乘,vector保留系数
void calcGx(){
    g = vector<Module>(k + 1, 0);
    // (x+3)*(x+3^2)*...
    // g * (x + pow3) = g * x + g * pow3
    g[k] = -3;
    g[k - 1] = 1;
    int pow3 = -9;
    // 一共有k项,前i项相乘有(i+1)个参数(从k往前)
    for (int i = 0; i < k - 1;i++){
        // temp result
        vector<Module> tt(k + 1, 0);
        // copy
        for (int j = k - i - 1; j <= k;j++){
            tt[j] = g[j];
        }
        // g = g * pow3
        for (int j = k - i - 1; j <= k;j++){
            g[j] = (g[j] % MOD) * pow3 % MOD;
        }
        // g = g + tt * x (也就是tt向左移动一位)
        for (int j = k - i - 1; j < k;j++){
            g[j] = (g[j] + tt[j + 1]) % MOD;
        }
        g[k - i - 2] = 1;   // 最高次一定是1
        pow3 *= 3;
        pow3 %= MOD;
    }
}

void calcRx(){
    vector<Module> &gx = g;
    // dx最高n次,但是乘了x^k
    vector<Module> dx(modules.size() + k, 0);
    for (int i = 0; i < modules.size();i++){
        dx[i] = modules[i] % MOD;
    }
    for (int i = 0; i < modules.size();i++){
        int t = dx[i];  // 最高次
        for (int j = 0; j < gx.size();j++){
            dx[i + j] = (dx[i + j] - gx[j] * t % MOD) % MOD;
        }
    }
    for (int i = dx.size() - gx.size() + 1; i < dx.size();i++){
        if(-dx[i] < 0)
            rx.push_back(MOD + (-dx[i] % MOD));
        else
            rx.push_back(-dx[i] % MOD);
    }
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> w >> s;
    cin >> text;
    getModules(text);
    calcGx();
    calcRx();
    
    for (int i = 0; i < modules.size();i++){
        cout << modules[i] << "\n";
    }
    if(s != -1){
        for (int i = 0; i < rx.size();i++){
            cout << rx[i] << "\n";
        }
    }
    return 0;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-02-26 11:12:28  更:2022-02-26 11:15:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:54:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码