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.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值