NOIP2015模拟1

来源:互联网 发布:vb winhttp 编辑:程序博客网 时间:2024/05/17 06:31

传送门

http://218.62.22.209:8080/problem.php?id=3175
http://218.62.22.209:8080/problem.php?id=3176
http://218.62.22.209:8080/problem.php?id=3177

T1 相关月

题目大意

给出年份和两个月份,判断这两个月的第一天是否都是星期I,

题解

  • 就是判断I,J两个月份之间有多少天如果是7的倍数,就是相关月
  • 可以打表出闰年和平年的月份天数表
  • 判断闰年的方法复习一下
    • 1.能整除4,但不能整除100
    • 2.能整除400
const x:array[1..12]of longint=(31,28,31,30,31,30,31,31,30,31,30,31); y:array[1..12]of longint=(31,29,31,30,31,30,31,31,30,31,30,31);var n:longint; i,j,a,b,c,sum:longint;procedure swap(var a,b:longint);var c:longint;begin c:=a; a:=b; b:=c;end;begin readln(n); for i:=1 to n do  begin   readln(a,b,c); sum:=0;   if b>c then swap(b,c);   if ((a mod 100<>0)and(a mod 4=0))or(a mod 400=0)   then for j:=b to c-1 do inc(sum,y[j])   else for j:=b to c-1 do inc(sum,x[j]);   if sum mod 7=0   then writeln('YES')   else writeln('NO');  end;end.

T2 无限序列

题目大意

给定一个无限序列的产生方法:初始序列为1,然后每次1变10,0变1,进行无限次操作产生无限序列,对于询问[L,R]内的1的个数,L,R<=263

题解

我们观察一下这个无限序列的产生过程
1,10,101,10110,10110101……
我们可以发现,从第三次开始,第I次得到的序列为第I-1次的序列后接上第I-2次的序列,即斐波那契的构成方法
对于询问[L,R]可以变成f(1,R)-f(1,L-1)
最多91次就可以得到263长度的序列了,所以我们与按操作次数处理出该串内的1的个数,对于超过的部分我们可以发现它也包含某次操作的字符串,通过截取每次已知答案的长度,直到吻合已知答案的长度

var ans:array[0..100,1..2]of int64; i,j,k:longint; n:longint; a,b,c,d,lin,linn:int64;function f(a,b:int64):int64;var i,tt:longint;begin if a=0 then exit(0); for i:=b downto 1 do  if ans[i,1]<=a  then begin tt:=i; break; end; f:=ans[tt,2]+f(a-ans[tt,1],tt);end;begin a:=1; b:=1; c:=1; d:=2; ans[1,1]:=1; ans[1,2]:=1; ans[2,1]:=2; ans[2,2]:=1; for i:=3 to 91 do  begin   lin:=a+b; linn:=c+d;   ans[i,1]:=linn; ans[i,2]:=lin;   a:=b; b:=lin; c:=d; d:=linn;  end; readln(n); for i:=1 to n do  begin   readln(a,b);   writeln(f(b,91)-f(a-1,91));  end;end.

T3 删数

题目大意

给定n个数,不断删除一段数,直到全删完,删除有两种方法,从左面第一个开始删到第I个,或者从右面第一个删到第I个

题解

区间DP,也就是说从左面删除一部分[1,I]再从右面删除另一部分[I+1,N],分左右DP
左面dp[1,i]=max(dp[1,i],dp[1,j]+f(j+1,i)) (1<=j<=i-1)
右面dp[i,n]=max(dp[i,n],f(i,j)+dp[j+1,n]) (i<=j<=n-1)
f(i,j)表示从i删到j的值
初始化dp[i,n]=f(i,n) , dp[1,i]=f(1,i)

var dp:array[0..1000,1..2]of longint; x:array[0..1000]of longint; i,j,k:longint; n,ans:longint;function max(a,b:longint):longint;begin if a>b then exit(a) else exit(b);end;function f(l,r:longint):longint;begin if l=r then exit(x[l]) else exit(abs(x[r]-x[l])*(r-l+1));end;begin readln(n); for i:=1 to n do  read(x[i]); for i:=1 to n do  dp[i,1]:=f(1,i); for i:=1 to n do  dp[i,2]:=f(i,n); for i:=2 to n do  for j:=1 to i-1 do   dp[i,1]:=max(dp[i,1],dp[j,1]+f(j+1,i)); dp[n,2]:=x[n]; for i:=n-1 downto 1 do  for j:=i to n-1 do   dp[i,2]:=max(dp[i,2],dp[j+1,2]+f(i,j)); dp[0,1]:=0; dp[n+1,2]:=0; for i:=1 to n do  ans:=max(ans,dp[i,1]+dp[i+1,2]); writeln(ans);end.
0 0
原创粉丝点击