CSP202112-3 登机牌条码

只得了50分

#include <bits/stdc++.h>
using namespace std;

int w, s;
string ring;
vector<int> num, code, arr; //码字数组

int judge(char ch)
{
	if ('0' <= ch && ch <= '9')
		return 0;
	else if ('A' <= ch && ch <= 'Z')
		return 1;
	else if ('a' <= ch && ch <= 'z')
		return 2;
	return -1;
}

int modify(char ch)
{
	if ('0' <= ch && ch <= '9')
		return ch - '0';
	else if ('A' <= ch && ch <= 'Z')
		return ch - 'A';
	else if ('a' <= ch && ch <= 'z')
		return ch - 'a';
	return -1;
}

void solve(int a, int b)
{
	// 0 数字 1 大写 2 小写
	if (a == 0) //之前是数字
	{
		if (b == 1)//大写
			num.push_back(28);
		else if (b == 2)//小写
			num.push_back(27);
	}
	else if (a == 1) //大写
	{
		if (b == 0)//数字
			num.push_back(28);
		else if (b == 2)//小写
			num.push_back(27);
	}
	else if (a == 2) //小写
	{
		if (b == 0)//数字
			num.push_back(28);
		else if (b == 1)//大写
		{
			num.push_back(28);
			num.push_back(28);
		}

	}
}

void Number()//求数字序列
{
	int n = ring.size();
	int a = 1, b;
	for (int i = 0; i < n; i++)
	{

		b = judge(ring[i]);
		//切换模式
		if (a != b)
		{
			// 0 数字 1 大写 2 小写
			solve(a, b);
		}
		num.push_back(modify(ring[i]));
		a = b;
	}
}

void Code() //求码字
{
	//求码字
	int n = num.size();
	if (n % 2 == 1)
		num.push_back(29);
	for (int i = 0; i < n; i += 2)
	{
		code.push_back(num[i] * 30 + num[i + 1]);
	}
	n = code.size();//有效数据个数
	int x = s != -1 ? pow(2, s + 1) : 0; //校验码字个数
	int y = (n + 1 + x) % w; //多的个数
	int k = (y == 0) ? y : w - y;//填充码字个数
	//长度码字
	arr.push_back(k + n + 1);
	//数据码字
	for (int i = 0; i < n; i++)
		arr.push_back(code[i]);
	//填充码字
	for (int i = 0; i < k; i++)
		arr.push_back(900);
}

//求g(x)
vector<int> calg(int k)
{
	vector<int> g(k + 1, 0);
	g[0] = -3, g[1] = 1;

	for (int i = 2; i <= k; i++)
	{
		vector<int> temp(g.begin(), g.end());
		g[0] = 0;//向前进一位
		int a = -9;
		for (int j = 1; j <= k; j++)
			g[j] = temp[j - 1];
		for (int j = 0; j <= k; j++)
		{
			temp[j] = (temp[j] * a) % 929;
			g[j] = (g[j] + temp[j]) % 929;
		}
		a = (a * 3) % 929;
	}
	return g;
}

//求 d(x)
vector<int> cald(int n, int k)
{
	vector<int> d(n + k, 0);

	for (int i = 0; i < n; i++)
		d[n + k - i - 1] = arr[i];
	return d;
}

void solve()//求校验码
{
	int n = code.size();
	if (s == -1)
		return;
	else
	{
		int k = pow(2, s + 1);// k 是校验码字个数
		n  = arr.size();//总个数
		vector<int> g = calg(k);
//		for (int x : g)
//			cout << x << " ";
//		cout << endl;
		vector<int> d = cald(n, k);
//		for (int x : d)
//			cout << x << " ";
//		cout << endl;

		// 计算r(x) 余数
		int glen = g.size(), dlen = d.size();
		while (dlen >= glen)
		{
			int x = (d[dlen - 1] / g[glen - 1]) % 929;
			int idx = 0;
			for (int i = dlen - glen; i < dlen; i++)
			{
				d[i] -= (g[idx++] % 929 * x % 929) % 929;
			}
			dlen --;
		}
		//去掉头部的0
		int i = glen - 2;
		while (d[i] == 0)
			i--;
		for (; i >= 0; i--)
		{
			d[i] = (-d[i]) % 929;
			if (d[i] < 0)
				d[i] += 929;
			arr.push_back(d[i]);
		}
	}

}

void outplay()//求码字序列
{
	int n = arr.size();
	for (int i = 0; i < n; i++)
		cout << arr[i] << '\n';
}

int main()
{
	cin >> w >> s;
	cin >> ring;

	Number();

	Code();

	solve();

	outplay();


	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值