这一套题怎么说呢,难的细节比较少,水的细节有点多,这第一题呢,计算加判断就行了,但是9个小时前的我,就因为打错了一个细节方面的问题(我是不会告诉你是怎么错),就与100分失之交臂,跌倒了0分的谷底,这就是差之毫厘失之千里!第二题很简单,DP直接过,比01背包还简单。第三题,呵呵,我用单源最短路径做,华丽丽地40分超时(人家对环合拓补排序还不懂嘛~~)第4题,我以为是DP,结果只是简单的BFS;
T1:Problem:某人总是花很多时间给父母打电话。有一次他记录了打电话的开始时间和结束时刻t1和t2,请你帮他算算此次通话一共用了多少秒。又有一次,他记录了打电话的开始时刻t1和通话的时间长度len,请你帮他计算他在什么时刻结束通话。
已知每次通话时间小于24个小时。
Input:输入文件phone.in的第一行为一个正整数T,表示了数据组数。
接下来T行,每行第一个数为k:
如果k = 0,接下来包含两个时间t1和t2,表示了打电话的开始时间和结束时刻,用一个空格隔开,时间格式为HH:MM:SS,其中0≤HH≤23,0≤MM,SS≤59。HH、MM和SS都是两位数字,因此0:1:2是不合法的时间(应写作00:01:02)。你应该对这个询问输出通话时间长度,答案一定为区间[0,86400)之内的非负整数。
如果k=1,接下来包含一个时间t1和一个非负整数len,表示了打电话的开始时刻与通话时间长度,用一个空格隔开,时间格式同为HH:MM:SS,同样时间小于24个小时,即len<86400。你应该对这个询问输出结束通话的时刻,同为HH:MM:SS格式。
Output
input:4
0 01:02:03 04:05:06
0 23:59:59 00:00:00
1 00:00:03 3
1 23:59:58 4
output:10983
1
00:00:06
00:00:02
思路:很简单,看看是那种询问,在化为秒数,计算没判断(我的错在于len只有1位,答案错误get)
伪代码: readln(s);
if s[1]='0' then
begin
a:=(ord(s[3])-48)*10+ord(s[4])-48;
b:=(ord(s[6])-48)*10+ord(s[7])-48;
c:=(ord(s[9])-48)*10+ord(s[10])-48;
a1:=(ord(s[12])-48)*10+ord(s[13])-48;
b1:=(ord(s[15])-48)*10+ord(s[16])-48;
c1:=(ord(s[18])-48)*10+ord(s[19])-48;
x:=a*3600+b*60+c;
y:=a1*3600+b1*60+c1;
if y<x then y:=y+86400;
writeln(y-x);
end;
if s[1]='1' then
begin
a:=(ord(s[3])-48)*10+ord(s[4])-48;
b:=(ord(s[6])-48)*10+ord(s[7])-48;
c:=(ord(s[9])-48)*10+ord(s[10])-48;
l:=length(s);
s1:=copy(s,12,l-12+1);
val(s1,y);
x:=(a*3600+b*60+c+y)mod 86400;
c:=x mod 60;
b:=(x div 60)mod 60;
a:=x div 3600;
if a<10 then write('0');
write(a,':');
if b<10 then write('0');
write(b,':');
if c<10 then write('0');
writeln(c);
end;
T2:
problem:某地铁沿线共设N站,可分为U(地面式)、D(地下式)和C(复合式)三种类型。为避免单调,相邻地铁站的类型不能重复。同时,由于地铁站所处环境和地质条件有所差异,每个站点按不同类型的建设成本也不尽相同。现给定各站点的三种建设成本,请计算出该地铁线的最低总造价。
input:3
1 99 99
99 1 99
99 99 1
output:
3
思路:很简单,跟01背包差不多,直接100分,设f[i,j]为在1到i站,i站为类型j的最小成本,方程式就是 if (j<>k) then
f[i,j]:=min(f[i,j],f[i-1,k]+a[i,j]);
伪代码: for i:=2 to n do
begin
for j:=1 to 3 do
begin
for k:=1 to 3 do
begin
if (j<>k) then
f[i,j]:=min(f[i,j],f[i-1,k]+a[i,j]);
end;
end;
end;
problem:X先生来到了一个奇怪的国家旅行。这个国家有N个城市,每个城市均有且仅有一个机场,但是这机场所有航班只飞往一个城市。每个城市有一个游览价值,第i个城市的游览价值为A[i]。
现在他想知道,从第i个城市出发,并只坐飞机飞往下一个城市,游览价值之和最多是多少(一个城市游览多次只计算1次游览价值)
input:
8 5 4 3 2 1 1 1 1 2 3 1 1 2 7 6 8outpu t:
12 12 12 14 13 2 2 1思路:比赛是我对每个i城市进行一次spfa,结果华丽丽超时,正解是拓补排序,先确认i城市在不在某个回路中,在根据在和不在的情况分别进行递归。
伪代码:
bz1:=false;
while not bz1 do
begin
bz1:=true;
for i:=1 to n do
begin
begin
if (father[i]=0)and(not hl[i]) then
begin
hl[i]:=true;
bz1:=false;
dec(father[f[i]]);
end;
end;
end;
end;//判断在不在某回路
procedure find_1(x:longint);
begin
bz[x]:=true;
sum:=sum+a[x];
if not bz[f[x]] then find_1(f[x]);
vis[x]:=sum;
end;//在回路的情况
procedure find_2(x:longint);
begin
bz[x]:=true;
if not bz[f[x]] then find_2(f[x])
else sum:=vis[f[x]];
sum:=sum+a[x];
vis[x]:=sum;
end;//不在回路的情况
T4:problem:小明完成了这样一个数字生成游戏,对于一个不包含0的数字s来说,有以下3种生成新的数的规则:
1.将s的任意两位对换生成新的数字,例如143可以生成341,413,134;
2.将s的任意一位删除生成新的数字,例如143可以生成14,13,43
3.在s的相邻两位之间s[i],s[i + 1]之间插入一个数字x,x需要满足s[i]<x<s[i + 1],即比它插入位置两边的数小。例如143可以生成1243,1343,但是不能生成1143,1543等。
现在小明想知道,在这个生成法则下,从s开始,每次生成一个数,可以用新生成的数生成另外一个数,不断生成直到生成t至少需要多少次生成操作。
另外,小明给规则3又加了一个限制,即生成数的位数不能超过初始数s的位数。若s是143,那么1243与1343都是无法生成的;若s为1443,那么可以将s删除4变为143,再生成1243或1343。
input: 143
3
134
133
32
output
1
-1
4
PS:143-》13-》123-》23-》32
思路:bfs,在输入s后就开始预处理,按3种情况增加对列
伪代码: for i:=1 to l1-1 do
begin
for j:=i+1 to l1 do
begin
str(d[head,1],s1);
ch:=s1[i];
s1[i]:=s1[j];
s1[j]:=ch;
val(s1,x);
if (s<>s1)and(bz[x]=0) then
begin
tail:=tail mod 1000000+1;
d[tail,1]:=x;
d[tail,2]:=d[head,2]+1;
bz[x]:=d[tail,2];
end;
end;
end;//两两交换
for i:=1 to l1 do
begin
str(d[head,1],s1);
delete(s1,i,1);
val(s1,x);
if (s<>s1)and(bz[x]=0) then
begin
tail:=tail mod 1000000+1;
d[tail,1]:=x;
d[tail,2]:=d[head,2]+1;
bz[x]:=d[tail,2];
end;
end;//删除其中一位
str(d[head,1],s1);
if l1<l then
begin
for i:=1 to l1-1 do
begin
for j:=ord(s1[i])-47 to ord(s1[i+1])-49 do
begin
if j=0 then continue;
s2:=copy(s1,1,i)+chr(j+48)+copy(s1,i+1,l1-i);
val(s2,x);
if (s<>s2)and(bz[x]=0) then
begin
tail:=tail mod 1000000+1;
d[tail,1]:=x;
d[tail,2]:=d[head,2]+1;
bz[x]:=d[tail,2];
end;
end;
end;
end;//插入j
然后就是读入并判断。
希望明天能更上一层楼,相信自己
希望这篇文章能对大家有帮助