题目链接:Good Morning
题目大意:按键盘上的数字,只能在此位置的基础上往右往下按,要求输出与所给值差的绝对值最小的数
AC代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <string> 5 using namespace std; 6 const int maxn=1e9+10; 7 int a[10][10]; 8 bool vis[210]; 9 int f[210]; 10 int k; 11 12 bool judge(int x) 13 { 14 int tot=0; 15 int s[10]; 16 for( ;x;x/=10 ) 17 { 18 s[++tot]=x%10; 19 } 20 for(int i=tot; i>1; i-- )//判断每一位是否符合题目所给的输出条件 21 { 22 if( !a[s[i]][s[i-1]] ) return false; 23 } 24 return true; 25 } 26 27 void init() 28 { 29 //打表1.a[i][j]表示从i键可以到j键打表为1,其他从i不可到的键为0 30 a[1][1]=1; a[1][2]=1; a[1][3]=1; a[1][4]=1; a[1][5]=1; a[1][6]=1; a[1][7]=1; a[1][8]=1; a[1][9]=1; a[1][0]=1; 31 a[2][2]=1; a[2][3]=1; a[2][5]=1; a[2][6]=1; a[2][8]=1; a[2][9]=1; a[2][0]=1; 32 a[3][3]=1; a[3][6]=1; a[3][9]=1; 33 a[4][4]=1; a[4][5]=1; a[4][6]=1; a[4][7]=1; a[4][8]=1; a[4][9]=1; a[4][0]=1; 34 a[5][5]=1; a[5][6]=1; a[5][8]=1; a[5][9]=1; a[5][0]=1; 35 a[6][6]=1; a[6][9]=1; 36 a[7][7]=1; a[7][8]=1; a[7][9]=1; a[7][0]=1; 37 a[8][8]=1; a[8][9]=1; a[8][0]=1; 38 a[9][9]=1; 39 a[0][0]=1; 40 41 memset(vis,false,sizeof(vis)); 42 memset(f,-1,sizeof(f)); 43 //打表2,标记0到210之间所有符合输出条件的数 44 for(int i=0;i<=210; i++ ) 45 { 46 if( judge(i) ) vis[i]=true; 47 } 48 //打表3,暴力试i的符合输出的数,试i-1,i-2,i-3,,,2,1,0; i; i+1,i+2,i+3,....i+210 49 for(int i=1; i<=200; i++ ) 50 { 51 for(int j=0; j<=210; j++ ) 52 { 53 if( i-j>=0 && vis[i-j] ) 54 { 55 f[i]=i-j; 56 break; 57 } 58 if( i+j<=210 && vis[i+j] ) 59 { 60 f[i]=i+j; 61 break; 62 } 63 } 64 } 65 } 66 67 int main() 68 { 69 int t; 70 scanf("%d",&t); 71 init(); 72 while( t-- ) 73 { 74 scanf("%d",&k); 75 printf("%d ",f[k]); 76 } 77 return 0; 78 }