题目大意
阅兵式上,国王见到了很多新奇东西,包括一台安卓手机。他很快对手机的图形解锁产生了兴趣。 解锁界面是一个 3×3 的正方形点阵,第一行的三个点标号 1,2,3,第二行的三个点标号 4,5,6,第三行的三个点标号 7,8,9。密码本身是一段序列,表示经过点的先后顺序,但遵循如下规则: 1. 密码至少经过四个点。 2. 不能重复经过同一个点。 3. 路径上的中间点不能跳过,除非已经被经过(3427 是合法的,但 3724 不合法)。 他想设置的密码的长度为正整数 k(1≤k≤9),密码序列为 s1s2...sk(0≤si<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;
}