题目信息:
骗分解读:
这个题主要是让我们计算编码后的码字序列,码字序列由两个部分组成,编码部分和校验部分。由于校验码实在是太麻烦了,对于骗分来说,我们可以不去看,所以我们只需要去考虑没有校验码的情况(s=-1)。
观察给出的样例,我们不难发现,这个题目编码部分可以分为三个部分:
1.正常编码
这部分只要对照编码表进行数字转换就可以
2.模式转换
这部分具有一定的规律,具体规律如下:
大写转小写:27
大写转数字:28
数字转小写:27
数字转大写:28
小写转数字:28
小写转大写:28 28(先转数字,再转大写)
3.填充
如果编码长度为奇数,则填充29
求内容码字:
码字的结构可以分为
当w=4,s=-1时,长度应该为4的倍数,而内容码字已经占了4个,加上长度占位1,所以填充长度应为3,填充内容为900
故结果为
整体思路可以分为:
1.计算编码
2.求码字
3.求填充长度
坑点:
1.开始时是大写模式,其他模式需要转化
代码:
#include <bits/stdc++.h>
using namespace std;
string s;
int n,f;
int a[1005],b[1005];
int main()
{
cin>>n>>f>>s;
int l=s.length();
int o=0;
for(int i=0;i<l;i++)
{
int x;
if(s[i]>='a'&&s[i]<='z')
{
if(i==0)
{
a[o++]=27;
}
x=s[i]-'a';
}
if(s[i]>='A'&&s[i]<='Z')
{
x=s[i]-'A';
}
if(s[i]>='0'&&s[i]<='9')
{
if(i==0)
{
a[o++]=28;
}
x=s[i]-'0';
}
a[o++]=x;
if((s[i]>='A'&&s[i]<='Z')&&(s[i+1]>='a'&&s[i+1]<='z'))
{
// cout<<"big to small"<<endl;
a[o++]=27;
}
if((s[i]>='A'&&s[i]<'Z')&&(s[i+1]>='0'&&s[i+1]<='9'))
{
// cout<<"big to num"<<endl;
a[o++]=28;
}
if((s[i]>='0'&&s[i]<='9')&&(s[i+1]>='a'&&s[i+1]<='z'))
{
// cout<<"num to small"<<endl;
a[o++]=27;
}
if((s[i]>='0'&&s[i]<='9')&&(s[i+1]>='A'&&s[i+1]<='Z'))
{
// cout<<"num to big"<<endl;
a[o++]=28;
}
if((s[i]>='a'&&s[i]<='z')&&(s[i+1]>='0'&&s[i+1]<='9'))
{
// cout<<"small to num"<<endl;
a[o++]=28;
}
if((s[i]>='a'&&s[i]<='z')&&(s[i+1]>='A'&&s[i+1]<='Z'))
{
// cout<<"small to big"<<endl;
a[o++]=28;
a[o++]=28;
}
}
// cout<<o<<endl;
if(o%2==1)
{
a[o++]=29;
}
// for(int i=0;i<o;i++)
// {
// cout<<a[i]<<" ";
// }
int p=0;
for(int i=0;i<o;i+=2)
{
b[p++]=a[i]*30+a[i+1];
}
// cout<<p<<endl;
int t=(p+1)%n;
if(t>0)
{
for(int i=0;i<n-t;i++)
{
b[p++]=900;
}
}
cout<<p+1<<endl;
for(int i=0;i<p;i++)
{
cout<<b[i]<<endl;
}
return 0;
}
/*
4 -1
HE1lo
5 -1
HE1lo5 -1
HE1lo
6 -1
HE1lo
3 -1
HeL
*/