hdu 5641 King's Phone(模拟)

题目大意

阅兵式上,国王见到了很多新奇东西,包括一台安卓手机。他很快对手机的图形解锁产生了兴趣。

解锁界面是一个 3 \times 33×3 的正方形点阵,第一行的三个点标号 1, 2, 31,2,3,第二行的三个点标号 4, 5, 64,5,6,第三行的三个点标号 7, 8, 97,8,9。密码本身是一段序列,表示经过点的先后顺序,但遵循如下规则:

1. 密码至少经过四个点。

2. 不能重复经过同一个点。

3. 路径上的中间点不能跳过,除非已经被经过(34273427 是合法的,但 37243724 不合法)。

他想设置的密码的长度为正整数 k(1\le k\le 9)k(1k9),密码序列为 s_1 s_2...s_k(0\le s_i < INT\_MAX)s1s2...sk(0si<INT_MAX),他想知道这个密码序列是否合法,这个问题交给了你。
思路:

这道题就是一道简单的有一些陷阱的模拟题。他的陷阱在于他输入的n有可能大于9小于4,然后输入的每个数都不确定,所以你要先特判一下。

把不符合的直接输出然后continue掉。

剩下的我是创建了一个map数组,map[i][j]=1 把所有中间隔着东西的情况都赋值为1,判断 (i+j)/2是否出现过,如果没出现过就不合法。

AC代码:

/* ***********************************************
Author        :yzkAccepted
Created Time  :2016/3/12 19:21:58
TASK          :lol.cpp
LANG          :C++
************************************************ */

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <stack>
using namespace std;
typedef __int64 ll;

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int t,k,i,n;
    int s[20],vis[20],mp[20][20];
    scanf("%d",&t);
    memset(mp,0,sizeof(mp));
    mp[1][3]=1,mp[3][1]=1,mp[1][7]=1,mp[7][1]=1;
    mp[1][9]=1,mp[9][1]=1,mp[2][8]=1,mp[8][2]=1;
    mp[4][6]=1,mp[6][4]=1,mp[7][9]=1,mp[9][7]=1;
	mp[7][3]=1,mp[3][7]=1,mp[9][3]=1,mp[3][9]=1;
	
    while(t--)
    {
		memset(s,0,sizeof(s));
        int flag=1;
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
			scanf("%d",&s[i]);
            if(s[i]<=0 || s[i] > 9)
			{   
				flag=0;
			}
        }
		if(flag==0)
		{
			printf("invalid\n");
			continue;
		}
		if(n>9)	
			flag=0;
		else if(n<4)	
			flag=0;
		else{ 
            memset(vis,0,sizeof(vis));
            vis[s[1]]=1;
            int head=s[1];
            for(i=2;i<=n;i++)
            {
                int mid=(head+s[i])/2;
				if(vis[s[i]]==1)
				{	
					flag=0;
					break;
				}
				else if(mp[head][s[i]]==1 && vis[mid]==0 )
                {
                    flag=0;
                    break;
                }
                else{
                    vis[s[i]]=1;
                    head=s[i];
                }
            }
		}   
        
		if(flag==1)
                printf("valid\n");
            else
                printf("invalid\n");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值