HDU 6130 Kolakoski 打表

来源:互联网 发布:工资数据分析 编辑:程序博客网 时间:2024/06/05 15:44

    题意是说有一个数组,1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1,2,2,1……,如果将这个数组相同的数字合并成一个数就会变成1,22,11,2,1,22,1,22,11,2,11,22,1……,然后再来看这个新数组每一个数字的位数,最后发现构成的数组就是一开始的数组1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1,2,2,1……,现在要求出这个数组第n个数。

    这题找了找貌似没什么规律或者循环节可以直接找出第n位的数字,比赛时候看几乎没有人TLE,干脆直接打表来做了。先把前两个数确定下来为1,2,因为a[2]=2,所以一定可以知道对应的是两个数,那么a[3]也一定是等于2的,而a[3]=2,所以后面一定可以知道是两个1,具体有几个数直接用a[i]就可以往后直接进行赋值,然后后面的数因为不是1就是2,所以在确定了这个数之后,也可以马上找到后面的数,这样一直找下去,最后打表找出这个数组就可以了。

    下面AC代码:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int a[20000005];int init(){    int i,j;    int k;    int t;    a[1]=1;    a[2]=2;    k=2;    for(i=2;i<=10000000;i++)    {        //cout<<i<<" "<<a[i]<<endl;        t=k+a[i]-1;        for(j=k+1;j<=t;j++)        {            a[j]=a[j-1];        }        k+=a[i];        if(a[k-1]==1)            a[k]=2;        else            a[k]=1;    }    return 0;}int main(){    int T;    int n;    init();    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        cout<<a[n]<<endl;    }    return 0;}