题目及代码打包: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.