7-23 翻转车牌 (10分)

7-23 翻转车牌 (10分)

有一个奇数位(如5位)的车牌号,由基本数字(0~9)组成,问有多少车牌翻转180度后号码还是原来的车牌并且各位数字之和能被3整除。(csp-s2019初试题)

输入格式:
一个数字:n(<10),表示车牌号位数

输出格式:
输出所有满足要求的车牌号码(按字典序排列,每行一个号码),最后一行是满足要求的车牌号总数。

输入样例:

3

输出样例:

000
111
609
888
906
5

当有一半的数字确定后,可以翻转确定另一半数字。所以操作次数只有m=n/2+0.5次(+0.5完成奇偶的四舍五入)。观察数字可知(0,1,8)三个数翻转后还是本身,(6,9)可以相互变换。

例如:

  1. 当n=3时,操作次数应该是两次(a3由a1得到)
  2. 当n=4时操作次数也是两次(a4由a1得到, a3由a2得到)

另外,仅有奇数位数的车牌中心位限制在(0,1,8)三个数里。
例如:

  1. 三位车牌(X_X’ ),则下划线处不能填(6,9),仅在(0,1,8)里选择
  2. 四位车牌(X_ _X’),则下划线可以在(0,1,6,8,9)里选择变换
#include<bits/stdc++.h>
using namespace std;
#define rep(i, l, r) for(int i = l; i <= r; i++)
#define rep1(i, l, r) for(int i = l; i < r; i++)
int n, m;  // 输入 操作次数
int x[15], sum = 0;  // 当前车牌 当前车牌数字和
int ans = 0;   //总共符合要求的车牌数目
int b[3] = {0, 1, 8};  // 变为自身的数
int c[2][5] = {0, 1, 6, 8, 9,
			 0, 1, 9, 8, 6};  //可以相互转换的数
int dfs(int t){
	if(t > m){ //操作次数到了之后输出并计数
		if(sum % 3 == 0){
			for(int i = 1; i <= n; i++) cout << x[i];
			cout << endl;
			ans++; 
		}
	}
	else{ 
		if(t != n - t + 1){ //可以自由选择
			for(int i = 0; i < 5; i++){
				x[t] = c[0][i];   
				x[n - t + 1] = c[1][i];
				sum += (c[0][i] + c[1][i]);
				dfs(t + 1);
				sum -= (c[0][i] + c[1][i]);
			}
		}
		else{ //奇数中心位必须是从0,1,8中选择
			for(int i = 0; i < 3; i++){
				x[t] = b[i];
				sum += b[i];
				dfs(t + 1);
				sum -= b[i];
			}
		}
	}
}
int main(){
	cin >> n;
	m = n * 1.0 / 2 + 0.5;  //计算操作次数
	dfs(1);
	cout << ans << endl;
	return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值