Tyvj Q1028(调整法)

Q1028 - Unit7 - 堆积木

From Admin    Normal (OI)
总时限:10s    内存限制:128MB    代码长度限制:64KB

描述 Description

现在有N块积木,每块积木都有自重Weight和正常状态下的承重能力Force,现在要把这N块积木垂直的垒在一起,但是有可能某块积木的负重超过了它在正常状态下的承重能力,那么这块积木就有被压坏的危险,请问应该如何堆这N块积木使得N块积木中最大的压力指数最小。

这里定义压力指数为该积木的负重与其在正常状态下的承重能力的差值。

输入格式 InputFormat

第一行为一个正整数N,表示有N块积木。
第二行到第 N+1 行,每行两个整数数,分别是第i个积木的Weight和Force

输出格式 OutputFormat

输出共一行,表示最大压力指数的最小值。

样例输入 SampleInput [复制数据]

2
100 0
1000 100

样例输出 SampleOutput [复制数据]

0

数据范围和注释 Hint

样例解释:
把Weight为100的积木放在Weight为1000的积木上,下面积木的压力指数为100 - 100 = 0,另外一块积木的压力指数和它的相等。

对于30% 的数据,1 <= N <= 3
对于60% 的数据,1 <= N <= 1000
对于100%的数据,1 <= N <= 50000
对于100%的数据,1 <= Weight <= 10000,1 <= Force <= 10^9

时间限制 TimeLimitation

1s

来源 Source

tjz


对于最优方案:

因为F(N)-(w1+w2+..wn-1)<F(1)-(w2+...+wn-1+wn)

化简得  F(n)+wn<F1+w1

调整ing。。。

也就是说对于最优方案有 Fi+wi<Fi-1+wi-1


Program block;
uses math;
const
   maxn=50000;
var
   n,i,j,ans,totw:longint;
   w,f:array[1..maxn] of longint;

procedure qsort(l,r:longint);
var
   i,j,m,p:longint;
begin
   i:=l;
   j:=r;
   m:=w[(i+j) div 2]+f[(i+j) div 2];
   repeat
      while (w[i]+f[i]<m) do inc(i);
      while (w[j]+f[j]>m) do dec(j);
      if i<=j then
      begin
         p:=w[i];w[i]:=w[j];w[j]:=p;
         p:=f[i];f[i]:=f[j];f[j]:=p;
         inc(i);dec(j);
      end;
   until i>j;
   if (l<j) then qsort(l,j);
   if (i<r) then qsort(i,r);
end;
begin
   read(n);
   for i:=1 to n do
   begin
      read(w[i],f[i]);
   end;
   qsort(1,n);
   ans:=-f[1];
   totw:=0;
   for i:=1 to n do
   begin
      ans:=max(ans,totw-f[i]);
      inc(totw,w[i]);

   end;
   writeln(ans);

end.



Tyvj Q1033(线性扫描)

Q1033 - Unit9 - 智力值

From Admin    Normal (OI)
总时限:5s    内存限制:128MB    代码长度限制:64KB

描述 Description

WJ是个很聪明的人,他有一个智力值。 
和比他聪明的人(智力值大于WJ)辩论一次智力值会+2。
和比他笨的人(智力值小于等于WJ)辩论一次智力会+1。
然后每个人只能辩论一次。安排一个辩论顺序。使得辩论完后WJ的智商最高。

输入格式 InputFormat

第一行包含两个正整数n和k,表示要和WJ辩论的人数,以及WJ的初始智力值。
第二行包含n个正整数,表示这n个人的智力值。

输出格式 OutputFormat

第一行包含一个正整数,表示WJ最终智力值的最大值。

样例输入 SampleInput [复制数据]

5 91
88 90 92 94 98

样例输出 SampleOutput [复制数据]

99

数据范围和注释 Hint

数据范围:
   1<=n<=500 智力值范围<=1000

每次贪心贪比他聪明的人中最不聪明的



const
   maxn=5000;
var
   n,i,j,now,tot:longint;
   a:array[1..maxn] of longint;
procedure qsort(l,r:longint);
var
   i,j,m,p:longint;
begin
   i:=l;
   j:=r;
   m:=a[(l+r) div 2];
   repeat
      while a[i]<m do inc(i);
      while a[j]>m do dec(j);
      if i<=j then
      begin
         p:=a[i];
         a[i]:=a[j];
         a[j]:=p;
         inc(i);
         dec(j);
      end;
   until i>j;
   if (l<j) then qsort(l,j);
   if (i<r) then qsort(i,r);


end;
begin
   read(n,now);
   tot:=0;
   for i:=1 to n do read(a[i]);
   qsort(1,n);

   for i:=1 to n do
   begin
      if (now<a[i]) then inc(now,2)
      else inc(tot);
   end;
   writeln(tot+now);



end.

Tyvj P2064(点的向上维护)

P2064 - 「Poetize10」能量获取

From lydliyudong    Normal (OI)
总时限:10s    内存限制:128MB    代码长度限制:64KB

描述 Description

“封印大典启动,请出Nescafe魂珠!”随着圣主applepi一声令下,圣剑护法rainbow和魔杖护法freda将Nescafe魂珠放置于封印台上。封印台是一个树形的结构,魂珠放置的位置就是根节点(编号为0)。还有n个其它节点(编号1~n)上放置着封印石,编号为i的封印石需要从魂珠上获取Ei的能量。能量只能沿着树边从魂珠传向封印石,每条边有一个能够传递的能量上限Wi,魂珠的能量是无穷大的。作为封印开始前的准备工作,请你求出最多能满足多少颗封印石的能量需求?
注意:能量可以经过一个节点,不满足它的需求而传向下一个节点。每条边仅能传递一次能量。

输入格式 InputFormat

第一行一个整数n,表示除根节点之外其它节点的数量。
接下来n行,第i+1行有三个整数Fi、Ei、Wi,分别表示i号节点的父节点、i号节点上封印石的能量需求、连接节点i与Fi的边最多能传递多少能量。

样例输入 SampleInput [复制数据]

4
0 3 2
0 100 100
1 1 1
2 75 80

样例输出 SampleOutput [复制数据]

2

数据范围和注释 Hint

对于 100% 的数据,满足1<=n<=1000,0<=Fi<=n,0<=Ei,Wi<=100。

时间限制 TimeLimitation

各个测试点1s

此题贪心 贪最小的点,易证必最优解

Program energy;
const
   maxn=1000;
var
   n,i,j,ans:longint;
   f,e,w,num,hpos:array[0..maxn] of longint;
procedure swap(var a,b:longint);
var
   t:longint;
begin
   t:=a;a:=b;b:=t;
end;
function max(a,b:longint):longint;
begin
   if a>b then exit(a) else exit(b);
end;
function min(a,b:longint):longint;
begin
   if a<b then exit(a) else exit(b);
end;
procedure qsort(l,r:longint);
var
   i,j,m,p:longint;
begin
   i:=l;
   j:=r;
   m:=e[(l+r) div 2];
   repeat
      while (e[i]<m) do inc(i);
      while (e[j]>m) do dec(j);
      if (i<=j) then
      begin
         swap(e[i],e[j]);
         swap(f[i],f[j]);
         swap(w[i],w[j]);
         swap(num[i],num[j]);
         inc(i);dec(j);
      end;
   until i>j;
   if (l<j) then qsort(l,j);
   if (i<r) then qsort(i,r);

end;

procedure pour(x:longint);
var
   noww,i,j:longint;
begin
   noww:=maxlongint;
   i:=x;
   while (i<>0) do
   begin
      noww:=min(noww,w[i]);
      i:=hpos[f[i]];
   end;

   if (noww<e[x]) then exit;

   inc(ans);
   i:=x;
   while (i<>0) do
   begin
      dec(w[i],e[x]);
      i:=hpos[f[i]];
   end;
end;
begin
   readln(n);
   for i:=1 to n do
   begin
      read(f[i],e[i],w[i]);
      num[i]:=i;
   end;
   qsort(1,n);
   hpos[0]:=0;
   for i:=1 to n do hpos[num[i]]:=i;


//   for i:=1 to n do write(f[i],' ',e[i],' ',w[i]);

   ans:=0;
   for i:=1 to n do pour(i);
   writeln(ans);

end.

幸运字符串(ansistring)

幸运字符串(string)

【问题描述】

对于一个只包含0和1的字符串,如果A是幸运的,B也是幸运的,那么1AB1也是一个幸运的串。现在定义”0”是一个幸运字符串,请判断给定的字符串S是否是幸运的。

【输入格式】

第一行一个数字T,表示数据组数。

接下来T组数据,第一行字符串长度n,接下来一行一个只含01的字符串。

【输出格式】

T行,第i个串如果是幸运字符串那么输出”YES”,否则输出”NO”。

【样例输入】

3

4

1001

7

1100101

7

0110011

【样例输出】

YES

YES

NO

【数据范围】

      30%的数据满足n<=100;

50%的数据满足n<=300;

100%的数据满足n<=800,T<=10

 

未1A的原因,又没改ansistring

//string
var
   n,tt,i,j,now:longint;
   s:ansistring;
function sort(i,j:longint):boolean;
var
   k:longint;
begin







   if (i=j) then
   begin
      if s[i]='0' then exit(true)
      else exit(false);
   end;
 {
   if (s[i]='1') and (s[j]='1') then
   begin
      for k:=i+1 to j-2 do
         if (sort(i+1,k)) and (sort(k+1,j-1)) then exit(true);

   end;
 }
   exit(false);


end;
begin
   assign(input,'string.in');
   assign(output,'string.out');
   reset(input);
   rewrite(output);
   readln(tt);
   while (tt>0) do
   begin
      readln(n);
      readln(s);
      while (true) do
      begin
         i:=pos('1001',s);
         if (i=0) then break;
         delete(s,i,2);
         delete(s,i+1,1);
         dec(n,3);
      end;





      if (sort(1,n)) then writeln('YES')
      else writeln('NO');

      dec(tt);
   end;
   close(input);
   close(output);
end.

传纸条(看清题目)

传纸条(message)

【题目描述】

小N和小A上课喜欢传纸条。

传纸条是有风险的,为了在老师发现的时候不知道他们在讨论什么内容,他们发明了一系列的加密方式。

其中有一种是这样的:一个数字由两个字符串a和b表达,这个数字就是b在a中匹配的位置。比如,a=”abcd”,b=”c”,那么这个数字就是3。

但是这样会出现一个问题,a和b能够表达两个不同的数字:比如,a=“ababa”,b=”aba”时,那个数字可以是1也可以是3。

他们对这种现象很好奇,现在给定一个字符串a,求一个整数x使得对于任意一个长度大于x的串b,这一问题都不会出现。

【输入数据】

一个仅由小写字母组成的字符串a

【输出数据】

一行一个整数,表示x的最小值

【样例输入】

ababa

【样例输出】

3

【数据范围】

对于50%的数据,a的长度≤10,

对于100%的数据,a的长度≤100.


Program message;
var
   n,i,j,k,l,ans:longint;
   s:string;
function min(a,b:longint):longint;
begin
   if (a<b) then exit(a) else exit(b);
end;
function max(a,b:longint):longint;
begin
   if (a>b) then exit(a) else exit(b);
end;

begin
   assign(input,'message.in');
   assign(output,'message.out');
   reset(input);
   rewrite(output);


   readln(s);
   n:=length(s);
   ans:=0;
   for i:=1 to n do
      for j:=i+1 to n do
      begin
         k:=i;
         l:=j;
         while ((s[k]=s[l]) and (l<=n)) do
         begin
            inc(k);
            inc(l);
            if (l>n) then break;
         end;


         ans:=max(ans,k-i);

      end;
   writeln(ans);

   close(input);
   close(output);

end.