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;
}
View Code

 

posted @ 2016-10-24 20:12  声声醉如兰  阅读(214)  评论(0编辑  收藏  举报