1. 程式人生 > >2016.07.17【初中部 NOIP提高組 】模擬賽C(附題目及程式碼打包)

2016.07.17【初中部 NOIP提高組 】模擬賽C(附題目及程式碼打包)

題目及程式碼打包:https://yunpan.cn/cBUd8PexRccpz (提取碼:308b)
T1:GIFT
輸入的第一行為一個整數t。接下來t行,每行包含九個自然數。表示2^a+2^b+2^c+2^d+2^e+2^f+2^g+2^h+i
  40% t<=1000
  100% t<=100000 a,b,c,d,e,f,g,h<=60 i<=9223372036854775808
 經過計算髮現:最大的ans為:8*2^64+9223372036854775808
=18446744073709551616=2^64
qword可以存的最大的數是2^64-1!!!!!!少了一怎麼辦,我們可以用 分(da)類(biao)討論的思想處理最大的資料就ok了
PASCAL

var
    t,i,j,k,a:longint;
    f:array[0..60]of qword;
    ans,l:qword;
begin
    f[0]:=1;
    for i:=1 to 60 do
        f[i]:=f[i-1]*2;
    readln(t);
    for i:=1 to t do
    begin
        ans:=0;
        for j:=1 to 8 do
        begin
            read(a);
            ans:=ans+f[a];
        end;
        read
(l); if (ans=9223372036854775808)and(l=9223372036854775808) then writeln('18446744073709551616') else writeln(ans+l); end; end.

C++

#include <cstdio> 
#include <iostream>
#define fo(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
unsigned long
long a,b,c,d,e,f,g,h,ii,t; unsigned long long mi(unsigned long long x){ return 1LL<<x; } int main() { cin>>t; fo(i,1,t){ scanf("%llu%llu%llu%llu%llu%llu%llu%llu%llu\n",&a,&b,&c,&d,&e,&f,&g,&h,&ii); unsigned long long ans = mi(a)+mi(b)+mi(c)+mi(d)+mi(e)+mi(f)+mi(g)+mi(h)+ii; if (ans==0) {printf("18446744073709551616\n");} else printf("%llu\n",ans); } }

T2:NUMBER
給出一個整數 ,你可以對 進行兩種操作。
  1、將x變成4x+3
  2、將x變成8x+7
  問,最少通過多少次操作,使得x是1000000007的倍數?
對於50%的資料,答案不超過10
對於80%的資料,答案不超過1000
對於100%的資料,答案不超過100000
這道題可以使用Hash+BFS也可以用x*2+1 的方法
分別貼出程式碼
Hash+BFS

uses 
    math;

var
    x:longint;
    h,d,w:array [0..400000] of int64;

function hash(x:longint):boolean;
var
    y:longint;

begin

    y:=x mod 399989;
    while (h[y]<>0) and (h[y]<>x) do
    begin
        inc(y);
        if y>399989 then
            y:=0;
    end;
    if (h[y]=0) then
    begin
        h[y]:=x;
        exit(true);
    end else
        exit(false);

end;

function Bfs(x:longint):longint;
var
    i,j:longint;
    t:int64;

begin

    i:=0;
    j:=1;
    d[1]:=x;
    w[1]:=0;
    if (hash(x)) then;
    while i<j do
    begin
        inc(i);
        t:=(d[i]*4+3) mod 1000000007;
        if t=0 then
            exit(w[i]+1);
        if (hash(t)) then
        begin
            inc(j);
            w[j]:=w[i]+1;
            d[j]:=t;
        end;
        t:=(d[i]*8+7) mod 1000000007;
        if t=0 then
            exit(w[i]+1);
        if (hash(t)) then
        begin
            inc(j);
            w[j]:=w[i]+1;
            d[j]:=t;
        end;
    end;

end;

begin

    readln(x);
    writeln(Bfs(x mod 1000000007));

end.

2*x+1

var
    x,i,j:qword;
begin
    read(x);
    while x mod 1000000007<>0 do
    begin
        x:=(x*2+1)mod 1000000007 ;
        inc(i);
    end;
    if i mod 3<>0 then
        writeln(i div 3+1)
    else
        writeln(i div 3);
end.

T3:Circle
 給定三個點(不共線)的座標,要求以這三個點為圓心做三個圓,圓兩兩不相交,不包含,問三個圓的直徑和最大為多少。(下取整)
 使用均值不等式推導發現answer就為三個點所組成三角形的周長。
 除錯了n久原來是弗洛伊德打錯了。。。。

var
    t,i,j,k,s:longint;
    x1,x2,x3,y1,y2,y3:real;
function ab(x:real):real;
begin
    if x>0 then
        exit(x)
    else
        exit(-x);
end;
begin
    read(t);
    for i:=1 to t do
    begin
        read(x1,y1,x2,y2,x3,y3);
        writeln(trunc(
        (sqrt(sqr(abs(x1-x2))+sqr(abs(y1-y2))))+
        (sqrt(sqr(abs(x1-x3))+sqr(abs(y1-y3))))+
        (sqrt(sqr(abs(x3-x2))+sqr(abs(y3-y2))))
        ));
    end;
end.

T4:Travel
 給出一個有 個頂點 條邊的有向圖,對於一條邊長度為len的邊有兩種走法。
 1、如果a和b可以互達,則走過這條邊的時間為len
 2、如果a和b不可以互達,則走過這條邊的時間為2*len
 現在給出一個k,問,從頂點1到頂點n,滿足第二種走法不超過k次的最短時間是多少。
 注意:互達不僅僅指這兩點是否有直接的路相接,而是指遍歷一邊可以到達
 用floyed維護出互達的點,分層SPFA
 分層SPFA:
 dis[i,j]表示i這個點在走了j條點不互達的邊的距離
 

uses
    math;
var
    n,m,k,i,ch,start,finish,dist,j,q,ans:longint;
    d:array[1..20800]of longint;
    a,b,f,ft:array[0..130,0..130]of longint;
    dis:array[1..130,0..10]of longint;
    bz:array[1..108]of boolean;
    bk:array[1..108,1..108]of boolean;
procedure init;
begin
    readln(n,m,k);
    fillchar(a,sizeof(a),$7f div 3);
    fillchar(dis,sizeof(dis),$7f div 3);
    ch:=a[1,1];
    for i:=1 to  m do
    begin
        readln(start,finish,dist);
        if a[finish,start]<>ch then
        begin
            f[start,finish]:=1;
            f[finish,start]:=1;
        end;
        if a[start,finish]=ch then
        begin
            inc(b[start,0]);
            a[start,finish]:=dist;
            b[start,b[start,0]]:=finish;
            continue;
        end
        else
        if a[start,finish]>dist then
            a[start,finish]:=dist;
    end;
end;
procedure floyed;
var
  i,j,k:longint;
begin
    f:=a;
    for k:=1 to n do
        if i<>k then
        for i:=1 to n do
            for j:=1 to n do
                if (i<>j)and(j<>k)and(i<>k) then
                    if f[i,k]+f[k,j]<f[i,j] then 
                        f[i,j]:=f[i,k]+f[k,j];
    ft:=f;
    fillchar(f,sizeof(f),0);
    for i:=1 to n do
        for j:=1 to n do
            if not((ft[j,i]=ft[0,0])and(a[i,j]<>a[0,0])) then 
                f[i,j]:=1;
end;
procedure spfa;
var
    head,tail,now:longint;
begin
    dis[1,0]:=0;
    head:=0;
    tail:=1;
    d[1]:=1;
    bz[head+1]:=true;
    while head<tail do
    begin
        inc(head);
        now:=d[head];
        for i:=1 to b[now,0]do
        begin
            if f[now,b[now,i]]=1 then
            begin
                for j:=0 to k do
                begin
                    if dis[b[now,i],j]>dis[now,j]+a[now,b[now,i]] then
                    begin
                        dis[b[now,i],j]:=dis[now,j]+a[now,b[now,i]];
                        if bz[b[now,i]]=false then
                        begin
                            bz[b[now,i]]:=true;
                            inc(tail);
                            d[tail]:=b[now,i];
                        end;
                    end;
                end;
            end else
            begin
                for j:=0 to k-1 do
                begin
                    if dis[b[now,i],j+1]>dis[now,j]+a[now,b[now,i]]*2 then
                    begin
                        dis[b[now,i],j+1]:=dis[now,j]+a[now,b[now,i]]*2;
                        if bz[b[now,i]]=false then
                        begin
                            bz[b[now,i]]:=true;
                            inc(tail);
                            d[tail]:=b[now,i];
                        end;
                    end;
                end;
            end;
        end;
        bz[now]:=false;
    end;
end;
begin
    assign(input,'1782.in');reset(input);
    init;
    floyed;
    spfa;
    ans:=maxlongint;
    for i:=0 to k do
        if dis[n,i]<>ch then
            ans:=min(ans,dis[n,i]);
    if (ans=maxlongint)or(ans=ch) then
        writeln(-1)
    else
        writeln(ans);
end.