与你的日常,就是奇迹!|

CCF 202112-3 登机牌条码

这算是本人第一次写(debug)出来大模拟的题。成就感max!

知识点:

vector的查询(下标),插入(insert),复制(assign)

queue的遍历输出(不能用for)

最重要的——求解多项式:

参考文章:(14条消息) CSP 202112-3 登机牌条码 (详细图解)_PolarDay.的博客-CSDN博客_机票条形码在线读取

一个多项式乘上xn,对应的结果就是向量向右移动n个位置,低位补0。{0,-3,1}

一个多项式乘上一个系数,对应的结果就是向量的各位同时乘上这个系数。{27,-9}

然后我们将这两个结果得到的向量相加最终得到{27,-12,1},对应的多项式为x2-12x+27,正是多项式运算的结果

求解多项式模板:

 

最重要的——多项式取模:

  1. 将除数乘上一个系数,使得被除数减除数之后能消掉最高位
  2. 被除数减除数
  3. 得到的结果继续按照第一步的方法计算,直到最终结果的最高位小于除数

多项式取模模板:

 

卡了半天的——取模问题

卡在80分的时候知道自己算法啥的没有错了,肯定是哪个地方数过大了。

曾思考是否每次取模这样的操作会对最终结果有影响? 答案是否定的

当时卡在了计算3的k次方这个位置,看的出来当s = 8 时 k = 512,此时算出的结果有3512这么大,一定会爆的!

解决方法是自己写一个计算函数,并对每次结果取模。

long long Pow(int num,int index) {
    long long ans = 1;
    for(int i = 1; i <= index; i++) {
        ans *= num;
        ans %= 929;
    }
    return ans;
}

还有,对于取模问题的进一步研究:

参考文章:(14条消息) 数论-取模问题总结_Kobe_G的博客-CSDN博客_对一个数取模

1.两数相加再取模
(m + n) % p = (m%p + n%p) %p

2.两数相乘再取模
(m * n) % p = (m%p) * (n%p) %p

3.两数相减再取模
(m - n) % p = ((m%p - n%p) + p) %p

对于上面的公式,在三个数及以上的时候也可以使用,用法因具体情况而异

AC代码:

复制代码
#include<iostream>
#include<string>
#include<queue>
#include<cmath>
#include<vector>
using namespace std;
string str;
queue<long long>q,ans;
vector<long long>gx,gx_old,gx_new,dx;

long long Pow(int num,int index) {
    long long ans = 1;
    for(int i = 1; i <= index; i++) {
        ans *= num;
        ans %= 929;
    }
    return ans;
}

void cal(int k) {
    int l = dx.size()-gx.size();
    gx.insert(gx.begin(),l,0);
    int len = dx.size()-1;
    for(int i = len; i >= k ; i--) {
        int m = dx[i],leng = gx.size()-1;
        for(int j = i ; j >= 0 ; j--) {
            dx[j] -= gx[leng--] * m;
            dx[j] %= 929;
        }
    }
    for(int i = k-1 ; i >= 0; i-- ) {
        int n = -dx[i] % 929;
        if(n < 0) {
            n = 929 + n;
        }
        ans.push(n);
    }
}




void cal_gx(int k) {
    gx.insert(gx.begin(),1);
    gx.insert(gx.begin(),-3);
    for(int j = 2; j<=k; j++) {
        gx_old.assign(gx.begin(),gx.end());
        gx.insert(gx.begin(),0);
        long long temp = -Pow(3,j);
        for(int i = 0 ; i< gx_old.size(); i++) {
            gx[i] += gx_old[i] * temp;
            gx[i] %= 929;
        }
    }
}

void cal_dx(int k) {
    int t = ans.size();
    dx.insert(dx.begin(),ans.size()+1);
    while(t--) {
        dx.insert(dx.begin(),ans.front());
        ans.push(ans.front());
        ans.pop();
    }
    while(k--)
        dx.insert(dx.begin(),0);
}


void print() {
    while(!ans.empty()) { //注意不能使用for遍历
        cout << ans.front() << endl;
        ans.pop();
    }
}

int main() {
    int w,s,k=0;
    cin >> w >> s;
    cin >> str;
    if(s != -1)
        k = pow(2,(s+1));
    int flag = 0;//0 大写 1 小写 2 数字
    for(int i = 0 ; i < str.size(); i++) {
        if(str[i] >= 'A' && str[i] <= 'Z' && flag == 0) {
            q.push(str[i]-'A');
        } else if(str[i] >= 'a' && str[i] <= 'z' && flag == 1) {
            q.push(str[i]-'a');
        } else if(str[i] >= '0' && str[i] <= '9' && flag == 2) {
            q.push(str[i]-'0');
        } else {
            if(flag == 0 && str[i] >= 'a' && str[i] <= 'z') {
                q.push(27);
                flag = 1;
            } else if(flag == 0 && str[i] >= '0' && str[i] <= '9') {
                q.push(28);
                flag = 2;
            } else if(flag == 1 && str[i] >= 'A' && str[i] <= 'Z') {
                q.push(28);
                q.push(28);
                flag = 0;
            } else if(flag == 1 && str[i] >= '0' && str[i] <= '9') {
                q.push(28);
                flag = 2;
            } else if(flag == 2 && str[i] >= 'A' && str[i] <= 'Z') {
                q.push(28);
                flag = 0;
            } else if(flag == 2 && str[i] >= 'a' && str[i] <= 'z') {
                q.push(27);
                flag = 1;
            }
            i--;
        }
    }
    if(q.size()%2) q.push(29);
    while(!q.empty()) {
        int H = q.front();
        q.pop();
        int L = q.front();
        q.pop();
        ans.push(H*30+L);
    }
    if((ans.size()+1+k)%w != 0) {
        int temp = w-((ans.size()+1+k)%w);
        while(temp--) {
            ans.push(900);
        }
    }
    cout << ans.size()+1<< endl;
    cal_gx(k);
    cal_dx(k);
    cal(k);
    print();
}
复制代码

 

本文作者:夏莱发电厂的Sensei

本文链接:https://www.cnblogs.com/Sensei/p/16472062.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   夏莱发电厂的Sensei  阅读(155)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开
  1. 1 DIVE INTO SUMMER Blue Archive
DIVE INTO SUMMER - Blue Archive
00:00 / 00:00
An audio error has occurred.