King's Phone
Accepts: 310
Submissions: 2980
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
阅兵式上,国王见到了很多新奇东西,包括一台安卓手机。他很快对手机的图形解锁产生了兴趣。 解锁界面是一个 3×33 \times 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(1\le k\le 9)k(1≤k≤9),密码序列为 s1s2...sk(0≤si<INT_MAX)s_1 s_2...s_k(0\le s_i < INT\_MAX)s1s2...sk(0≤si<INT_MAX),他想知道这个密码序列是否合法,这个问题交给了你。
输入描述
第一行一个整数表示测试组数:T(0<T≤100000)T(0 < T\le100000)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\rightarrow 1 \rightarrow 6 \rightarrow 78→1→6→7 路径均没有中间点,所以合法。
题目读懂了,就能AC的一道暴力枚举的题目,一开始的时候觉得相关度数会有什么伏笔也有可能和计算几何相关,后来想的远了,回来也就费劲了,枚举的时候判断的地方少了一个,最终测试的时候实力RE。。。。。。
针对题干的几种情况:
这种暴力枚举的题目一定要谨慎,三个条件一定都要完成才行,第一个条件好判断,我们用一个vis【】来设定经过的点,0表示没有经过。1表示有经过,我们在最后的时候判断一下1的有4个以上就能保证第一个条件的成立。第二个条件在刚刚判断的时候再加上一个if(vis【】==1)输出不合法即可。
最后是暴力枚举跳过点的情况:
枚举条件:
我们在纸上写下安卓屏幕的3*3的矩阵:
1 2 3
4 5 6
7 8 9
明显从1-3 1-9 1-7 都是不能直接到的,这种路径情况会跳过点,属于不合法的情况,我们将从1-9都枚举出来就可以了,最终AC代码:#include<stdio.h>
#include<string.h>
using namespace std;
int vis[10];
int a[15];
int ok;
void merge(int x,int y)
{
if(x<1||x>9)
{
ok=0;
return ;
}
if(y<1||y>9)
{
ok=0;
return ;
}
if(vis[y]==1)
{
ok=0;
return ;
}
vis[y]=1;
if(x==1)
{
if(y==3&&vis[2]==0)
{
ok=0;
}
if(y==7&&vis[4]==0)
{
ok=0;
}
if(y==9&&vis[5]==0)
{
ok=0;
}
}
if(x==2)
{
if(y==8&&vis[5]==0)
{
ok=0;
}
}
if(x==3)
{
if(y==1&&vis[2]==0)
{
ok=0;
}
if(y==7&&vis[5]==0)
{
ok=0;
}
if(y==9&&vis[6]==0)
{
ok=0;
}
}
if(x==4)
{
if(y==6&&vis[5]==0)
{
ok=0;
}
}
if(x==6)
{
if(y==4&&vis[5]==0)
{
ok=0;
}
}
if(x==7)
{
if(y==1&&vis[4]==0)
{
ok=0;
}
if(y==3&&vis[5]==0)
{
ok=0;
}
if(y==9&&vis[8]==0)
{
ok=0;
}
}
if(x==8)
{
if(y==2&&vis[5]==0)
{
ok=0;
}
}
if(x==9)
{
if(y==1&&vis[5]==0)
{
ok=0;
}
if(y==3&&vis[6]==0)
{
ok=0;
}
if(y==7&&vis[8]==0)
{
ok=0;
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
ok=1;
memset(vis,0,sizeof(vis));
int k;
scanf("%d",&k);
scanf("%d",&a[0]);
if(a[0]>=1&&a[0]<=9)
vis[a[0]]=1;
else
{
ok=0;
}
for(int i=1;i<k;i++)
{
scanf("%d",&a[i]);
merge(a[i-1],a[i]);
}
if(ok==0)
{
//printf("yes\n");
printf("invalid\n");
}
if(ok==1)
{
int cont=0;
for(int i=1;i<=9;i++)
{
if(vis[i]==1)
cont++;
}
if(cont>=4)
{
printf("valid\n");
}
else
{
// printf("yes2\n");
printf("invalid\n");
}
}
}
}