问题描述
阅兵式上,国王见到了很多新奇东西,包括一台安卓手机。他很快对手机的图形解锁产生了兴趣。
解锁界面是一个 3×33 imes 33×3 的正方形点阵,第一行的三个点标号 1,2,31, 2, 31,2,3,第二行的三个点标号 4,5,64, 5, 64,5,6,第三行的三个点标号 7,8,97, 8, 97,8,9。密码本身是一段序列,表示经过点的先后顺序,但遵循如下规则:
1. 密码至少经过四个点。
2. 不能重复经过同一个点。
3. 路径上的中间点不能跳过,除非已经被经过(342734273427 是合法的,但 372437243724 不合法)。
他想设置的密码的长度为正整数 k(1≤k≤9)k(1le kle 9)k(1≤k≤9),密码序列为 s1s2...sk(0≤si<INT_MAX)s_1 s_2...s_k(0le s_i < INT\_MAX)s1s2...sk(0≤si<INT_MAX),他想知道这个密码序列是否合法,这个问题交给了你。
输入描述
第一行一个整数表示测试组数:T(0<T≤100000)T(0 < Tle100000)T(0<T≤100000) 。
每组数据占一行,每行第一个数 kkk,设置密码的长度;接着 kkk 个正整数,之间用空格隔开,表示密码序列 s1s2...sks_1s_2...s_ks1s2...sk。
输出描述
共 TTT 行。对每组数据,若合法输出 `valid`,否则输出 `invalid`。
输入样例
3 4 1 3 6 2 4 6 2 1 3 4 8 1 6 7
输出样例
invalid valid valid
Hint
对于第一组数据,111 到 333 跳过了路径上的点 222,所以不合法。
对于第二组数据,111 到 333 时点 222 已经被经过了,所以合法。
对于第三组数据,8→1→6→78
ightarrow 1
ightarrow 6
ightarrow 78→1→6→7 路径均没有中间点,所以合法。
一个简单的模拟题,首先判断序列长度是否合法,接着判断 1<s<9 ,4<k<9,再判断中点是否满足
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 using namespace std; 6 #define LL long long 7 int map[5][5]; 8 int a[10],b[10]; 9 int t,k,c,p,q; 10 bool f,f1,f2; 11 int change(int c,int i){ 12 if(c>6) a[i]=3,b[i]=c-6; 13 else if(c>3) a[i]=2,b[i]=c-3; 14 else a[i]=1,b[i]=c; 15 } 16 void fuc(int i){ 17 if(abs(a[i]-a[i-1])>1) f1=1; else f1=0; 18 if(abs(b[i]-b[i-1])>1) f2=1; else f2=0; 19 } 20 void judge(){ 21 map[a[1]][b[1]]=1; 22 for(int i=2;i<=k;i++) 23 { 24 if(map[a[i]][b[i]]) f=0; 25 map[a[i]][b[i]]=1; 26 fuc(i); 27 if(f1&&f2){ 28 if(map[2][2]==0) f=0; 29 } 30 else if(f1&&b[i]==b[i-1]){ 31 if(map[2][b[i]]==0) f=0; 32 } 33 else if(f2&&a[i]==a[i-1]){ 34 if(map[a[i]][2]==0) f=0; 35 } 36 if(f==0) return ; 37 } 38 } 39 int main(){ 40 scanf("%d",&t); 41 while(t--){ 42 memset(map,0,sizeof(map)); f=1; 43 cin>>k; 44 for(int i=1;i<=k;i++) 45 { 46 cin>>c; 47 if(c>9||c==0) f=0; 48 change(c,i); 49 } 50 if(f==0||k<4||k>9) 51 { 52 puts("invalid"); 53 continue; 54 } 55 judge(); 56 if(f) puts("valid"); 57 else puts("invalid"); 58 } 59 } 60 /* 61 9 62 9 1 2 3 4 5 6 7 8 9 63 */