有歧义的号码
时间限制:
10000ms
单点时限:
1000ms
内存限制:
256MB
-
10
样例输出
-
6 9
描述
小Hi参加了一场大型马拉松运动会,他突然发现面前有一位参赛者背后的号码竟然和自己一样,也是666。仔细一看,原来那位参赛者把自己号码帖反(旋转180度)了,结果号码999看上去变成了号码666。
小Hi知道这次马拉松一共有N名参赛者,号码依次是1~N。你能找出所有可能因为贴反而产生歧义的号码吗?
一个号码K可能产生歧义当且仅当反转之后的号码是合法的数字K',并且满足1 ≤ K' ≤ N且K' ≠ K。
例如:
3没有歧义,因为贴反之后不是合法的数字。
100没有歧义,因为001以0开头,不是合法号码。
101也没有歧义,因为贴反之后还是101本身。
假设N=10000000,则1025689有歧义,因为贴反之后变成6895201。如果N=2000000,则1025689没有歧义,因为6895201大于N。
输入
一个整数N。(1 ≤ N ≤ 100000)
输出
从小到大输出1~N之间所有有歧义的号码。每个号码一行。
思路:设M^′为将M旋转180度后得到的数字
–1⇒1,2⇒2,5⇒5,6⇒9,8⇒8,9⇒6
•M有歧义当且仅当
–M′是一个合法数字
–1≤M^′≠M≤N
•枚举
–M=1~N
–计算M^′=M
•k=M mod 10, M=M div 10,M^′=M^′∗10+k^′
–判断M′是否合法
•
•M′是否合法
–M模10是否为0
–1≤M^′≠M≤N
AC代码如下:
#include<stdio.h>
int n;
int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;i++)
{
int m=i;
if(m%10==0) continue;//个位数含有0的数字肯定不满足条件
bool flag=false;
int x=0;
while(m)
{
int k=m%10;
if(k==3 || k==4 || k==7) //出现这三个数字肯定不满足题意
{
flag=true;
break;
}
else if(k==6) k=9;//只有6、9这两个数字是变换了的
else if(k==9) k=6;
x=x*10+k;//计算歧义号码的大小
m/=10;
}
if(flag) continue;
if(x!=i && x>=1 && x<=n) printf("%d\n",i);
}
}
return 0;
}