Codeforces 689A Mike and Cellphone
题目大意:给出一个电话号,按出这个电话号需要一定的手指移动,问该种手指移动的方法是否能按出其他电话号,是的话输出NO,否则输出YES。
题目思路:模拟
#include<iostream> #include<algorithm> #include<cstring> #include<vector> #include<stdio.h> #include<stdlib.h> #include<queue> #include<math.h> #include<map> #define INF 0x3f3f3f3f #define MAX 100005 #define Temp 1000000000 #define MOD 1000000007 using namespace std; struct node { int movx,movy;//记录x,y坐标的移动信息 } q[MAX]; int Map[5][5],n,sx,sy; char str[50]; void Find(int num1,int num2,int pos) { int x1,y1,x2,y2; for(int i=1; i<=4; i++) { for(int j=1; j<=3; j++) { if(Map[i][j]==num1) { x1=i; y1=j; } if(Map[i][j]==num2) { x2=i; y2=j; } } } q[pos].movx=x2-x1; q[pos].movy=y2-y1; } void GetTemp() { for(int i=1; i<n; i++) { int num1=str[i-1]-'0'; int num2=str[i]-'0'; Find(num1,num2,i-1); } } int Check(int x,int y,int pos) { if(pos==n-1) return 1; int next_x=x+q[pos].movx; int next_y=y+q[pos].movy; if(next_x<1 || next_x>4 || next_y<1 || next_y>3) return 0; if(next_x==4 && next_y!=2) return 0; if(Map[next_x][next_y]==-1) return 0; else return Check(next_x,next_y,pos+1); } void Init()//初始化键盘 { memset(Map,-1,sizeof(Map)); for(int i=1; i<=3; i++) for(int j=1; j<=3; j++) Map[i][j]=(i-1)*3+j; Map[4][2]=0; } int Solve()//以每个数字为起点,做一次手指运动,看是否能获取合法的电话号码 { int ok; for(int i=1; i<=4; i++) { for(int j=1; j<=3; j++) { if(Map[i][j]!=-1 && (i!=sx||j!=sy)) { ok=Check(i,j,0); if(ok) return 1; } } } return 0; } int main() { int ok; Init(); while(scanf("%d",&n)!=EOF) { scanf("%s",str); for(int i=1; i<=4; i++)//得到初始点 { for(int j=1; j<=3; j++) { if(Map[i][j]==(str[0]-'0')) { sx=i; sy=j; break; } } } if(n==1) { printf("NO\n"); continue; } GetTemp();//获取当前号码的手指运动 int ok=Solve(); if(!ok) printf("YES\n"); else printf("NO\n"); } return 0; }