2016.09.15【初中部 NOIP提高组 】模拟赛C题解

来源:互联网 发布:麒麟网络 上市 编辑:程序博客网 时间:2024/06/05 02:49

哈哈哈哈哈哈哈哈!!!~~~~~~~

T1:

        题目大意:即给出n组l,r,求l~r的友好数对,设友好数对为(a,b),即a可以通过b旋转而得。

            这道题一上来就觉得是数位DP,我死定了,蒙蔽的打了个暴力。

            过了一会,我发现,我都不会做后面2题,于是我开始推转移方程。发现设了也会超时。

            这时我发现数据水,只有两百万,我想到了建立数据库。

            说干就干:

            设i=10~2000000的某个数旋转后的数k,保证k≤i,然后把它记录下来,即用个邻接矩阵c[i,j]表示i这个数,有第j的旋转的数为ans,要判重。最后枚举一下l~r,判断一下对应的数是否比l大,因保证比枚举的i小,所以不用判断小于r。


T2:

        题目大意:给定一个图,要求左上,右下对角线对称的路劲,求最短疲劳值。

           首先我们可以把线的两边对折,这样就变成了半个矩阵,同时问题就转化成了从左上角到折线的位置的最短路径的条数有多少。

            然后,我们可以用SPFA求单源最短路,这样起点到每个点的最短路就都有了。之后为了能够算出路径的条数,我们可以从起点开始,然后记录一下,有走过这里,或者没走过,记录一下。

最后,统计折线上的最短路的最小值,并把所有符合要求的路径的条数相加即可。

            莫名80分,不知道为什么。

T3:

第三题链表+堆,我不用链表随便high!

            建立一个最小堆,记录权值,左点,右点,然后维护一下(维护不仅要权值,还要左点),每次取堆顶,必须是符合没选过的。

取完后,在堆末找个符合条件的取代堆顶。

 while (bz[a[1]]+bz[b[1]]<>0)and(tot<>0) do                begin                        a[1]:=a[tot];                        b[1]:=b[tot];                        heap[1]:=heap[tot];                        dec(tot);                        heapdown(1);                end;                if (bz[a[1]]+bz[b[1]]=0) then                begin                        inc(ans);                        c[ans,1]:=a[1];                        c[ans,2]:=b[1];                        bz[a[1]]:=1;                        bz[b[1]]:=1;                end;                while (bz[a[tot]]+bz[b[tot]]<>0)and(tot<>0) do                        dec(tot);                if tot-1>0 then                begin                        a[1]:=a[tot];                        b[1]:=b[tot];                        heap[1]:=heap[tot];                        dec(tot);                        heapdown(1);                end;

可能去掉了这个,他的左边右边可以练,加入堆,继续做就可以了。

 t1:=0;                t2:=0;                for i:=c[ans,1] downto 1 do                        if (bz[i]=0) then                        begin                                t1:=i;                                break;                        end;                if t1<>0 then                for i:=c[ans,1] to n do                        if bz[i]=0 then                        begin                                if s[t1]<>s[i] then                                        t2:=i;                                break;                        end;                if (t1*t2<>0)and(bz[t1]+bz[t2]=0) then                begin                        inc(tot);                        heap[tot]:=abs(num[t1]-num[t2]);                        a[tot]:=t1;                        b[tot]:=t2;                        heapup(tot);                end;

0 0
原创粉丝点击