题意:链接
方法:分类讨论
解析:
Idea rozwiązania wzorcowego polega na przekształcaniu danego ciągu w = (k1,…, kn) przez
coś w rodzaju funkcji odwrotnej do h. Okazuje się, że dla dużych elementów ciągu w cofanie
funkcji h polega na zwykłym ich zmniejszaniu, a dla małych (nie większych niż 3) trzeba
czasem rozpatrywać pewne przypadki szczególne. Operacje wykonywane w algorytmie mają
tę własność, że ciąg dobry przekształcają w ciąg dobry, a zły — w zły. Proces ten doprowadza
w końcu do ciągu jednoelementowego, który oczywiście jest dobry (wtedy ciąg początkowy
też był dobry), lub do ciągu, o którym potrafimy stwierdzić, że na pewno jest zły (wtedy
początkowy był zły).
w:=(k1,…,kn)
while |w|>1 do begin
if w zawiera fragment k,0 dla k ∈ {1,3} then return false
Wykonaj kolejno następuj ące operacje na ciągu w:
zamien, je ´ zeli wyst˛epuje, pierwszy element 0 ˙ → 2
zamien, je ´ zeli wyst˛epuje, ostatni element 3 ˙ → 2
usun, je ´ zeli wyst˛epuje, ostatni element równy 1 ˙
zamien wszystkie fragmenty 1 ´ ,0 → 2
zamien wszystkie fragmenty 3 ´ ,0 → 2,2
zmniejsz wszystkie elementy o 1
看懂上面的波兰文你就AC了。
其实翻译过来大概是这个意思。
我们可以不断的将连接起来的串进行逆转换。
然后伪代码具体给出了方式。
如果当前序列仅剩一个元素则为可行。
如果在序列中存在一个元素为零,则如果他前面的元素不是1或3,则返回0.
这是为什么呢?
首先对于本题来说,显然我们可以通过手画来搞出来几个数据,然后我们可以发现其实所有的串是个斐波那契形式
每一个是上一个与上上一个的连接。
zamien, je ´ zeli wyst˛epuje, pierwszy element 0 ˙ → 2
上面那句话的意思是如果首位是0的话那么把它转成2.
zamien, je ´ zeli wyst˛epuje, ostatni element 3 ˙ → 2
上面那句话的意思是如果末位是3的话那么把它转成2.
然后就是什么找序列中有0的数
如果前一个是1,则用2替换两个数。
如果前一个是3,则用3替换两个数
然后所有元素-1,递归就好了。
这是为什么呢?
观察下表
3->101
5->10110101
其实总的规律就是什么两个0不能连起来啊
不能有101010这种串什么的。
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 100100
using namespace std;
int n;
int a[N];
int check()
{
while(n>1)
{
if(!a[1])a[1]=2;
if(a[n]==1)a[n]=-1;
else if(a[n]==3)a[n]=2;
for(int i=2;i<=n;i++)
{
if(!a[i])
{
if(a[i-1]==1)a[i]=-1,a[i-1]=2;
else if(a[i-1]==3)a[i]=a[i-1]=2;
else return 0;
}
}
int m=0;
for(int i=1;i<=n;i++)
{
if(a[i]!=-1)a[++m]=a[i];
}
n=m;
for(int i=1;i<=n;i++)a[i]--;
}
return 1;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
puts(check()?"TAK":"NIE");
}
}