POJ 3049(输出字母)

在一堆字母中找一段字母,使其中至少含有1个原音,2个辅音字母,且按字典序从小到大排列

果断搜

Program P3049;
var
   n,i,j,m:longint;
   a:array[1..26] of char;
   b:array['a'..'z'] of boolean;
   c:char;
procedure swap(var a,b:char);
var
   t:char;
begin
   t:=a;a:=b;b:=t;
end;
procedure dfs(father:longint;s:string;flag:boolean;l:longint);
var
   i:longint;
begin
   if l=n then
   begin
      if flag then writeln(s);
      exit;
   end;
   for i:=father+1 to m-(n-l)+1 do
      dfs(i,s+a[i],flag or b[a[i]],l+1);


end;
begin
   fillchar(b,sizeof(b),false);
   b['a']:=true;b['e']:=true;b['i']:=true;b['o']:=true;b['u']:=true;
   readln(n,m);
   for i:=1 to m do
   begin
      read(a[i]);
      read(c);
   end;
   for i:=1 to m-1 do
      for j:=i+1 to m do
         if ord(a[i])>ord(a[j]) then swap(a[i],a[j]);
   if n<3 then halt;
   dfs(0,'',false,0);


end.

POJ 2456(二分哲学)

这题普通的二分会T…………

法一:只循环60遍,用ans记录答案(见标程)

法二:进行特判,若l+1==r 则 m=(l+r+1) shl 1 否则 m=(l+r) shl 1

Program P2456;
const
   maxd=1000000000;
   maxn=100000;
var
   n,c,i,j,k:longint;
   a:array[1..maxn] of longint;
procedure sort(l,r:longint);
var
   m,i,k,head,tot,ans:longint;
begin
   for k:=1 to 60 do
   begin
      m:=(l+r) shr 1;
      head:=1;tot:=0;
      for i:=2 to n do
      begin
         if a[i]-a[head]>=m then
         begin
            inc(tot);
            head:=i;
         end;
      end;
      if tot>=c-1 then begin ans:=m; l:=m+1 end else r:=m-1;
   end;
   writeln(ans);

end;
procedure qsort(l,r:longint);
var
   i,j,m,p:longint;
begin
   i:=l;
   j:=r;
   m:=a[(l+r) shr 1];
   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,c);
   for i:=1 to n do read(a[i]);
   qsort(1,n);
   sort(1,maxd);

end.

POJ 3289(高精度乘法)

高精度乘法

Program P3289;
const
   maxn=40000;
   F=10;
type
   arr=record
       d:array[1..maxn] of longint;
       len,doc:longint;
       end;
var
   r,m:arr;
   y:longint;
   i:longint;
   a,b:arr;
function max(a,b:longint):longint;
begin
   if a<b then exit(b) else exit(a);
end;
procedure multipy(a,b:arr;var c:arr);
var
   i,j,len:longint;
begin
   fillchar(c,sizeof(c),0);
   c.len:=a.len+b.len;

   for i:=1 to a.len do
      for j:=1 to b.len do
      begin
         inc(c.d[i+j-1],a.d[i]*b.d[j]);
         inc(c.d[i+j],c.d[i+j-1] div F);
         c.d[i+j-1]:=c.d[i+j-1] mod F;
      end;
   while (c.d[c.len]=0) and (c.len>1) do dec(c.len);
   c.doc:=a.doc+b.doc;


end;
procedure to_arr(doc:longint;var c:arr);
var
   x,i,n:longint;
begin
   read(x);
   i:=0;
   while (x>0) do
   begin
      inc(i);
      c.d[i]:=x mod F;
      x:=x div F;
   end;
   c.len:=i;
   c.doc:=doc;
end;
Procedure jie(a:arr;x:longint;var c:arr);
begin
   if x=1 then begin c:=a; exit; end;
   fillchar(c,sizeof(c),0);
   if (x mod 2=0) then
   begin
      jie(a,x div 2,c);
      multipy(c,c,c);
   end
   else
   begin
      jie(a,x div 2,c);
      multipy(c,c,c);
      multipy(a,c,c);
   end;
end;
begin
   to_arr(2,r);
   r.len:=3;r.d[3]:=1;
   to_arr(0,m);
   read(y);
   jie(r,y,r);
   multipy(m,r,m);


   for i:=m.len downto m.doc+1 do write(m.d[i]);
   writeln;

end.

POJ 2390 (小数高精度乘法)

小数高精度乘法

m*(1+r/100)^y

Program P2390;
const
   maxn=40000;
   F=10;
type
   arr=record
       d:array[1..maxn] of longint;
       len,doc:longint;
       end;
var
   r,m:arr;
   y:longint;
   i:longint;
   a,b:arr;
function max(a,b:longint):longint;
begin
   if a<b then exit(b) else exit(a);
end;
procedure multipy(a,b:arr;var c:arr);
var
   i,j,len:longint;
begin
   fillchar(c,sizeof(c),0);
   c.len:=a.len+b.len;

   for i:=1 to a.len do
      for j:=1 to b.len do
      begin
         inc(c.d[i+j-1],a.d[i]*b.d[j]);
         inc(c.d[i+j],c.d[i+j-1] div F);
         c.d[i+j-1]:=c.d[i+j-1] mod F;
      end;
   while (c.d[c.len]=0) and (c.len>1) do dec(c.len);
   c.doc:=a.doc+b.doc;


end;
procedure to_arr(doc:longint;var c:arr);
var
   x,i,n:longint;
begin
   read(x);
   i:=0;
   while (x>0) do
   begin
      inc(i);
      c.d[i]:=x mod F;
      x:=x div F;
   end;
   c.len:=i;
   c.doc:=doc;
end;
Procedure jie(a:arr;x:longint;var c:arr);
begin
   if x=1 then begin c:=a; exit; end;
   fillchar(c,sizeof(c),0);
   if (x mod 2=0) then
   begin
      jie(a,x div 2,c);
      multipy(c,c,c);
   end
   else
   begin
      jie(a,x div 2,c);
      multipy(c,c,c);
      multipy(a,c,c);
   end;
end;
begin
   to_arr(2,r);
   r.len:=3;r.d[3]:=1;
   to_arr(0,m);
   read(y);
   jie(r,y,r);
   multipy(m,r,m);


   for i:=m.len downto m.doc+1 do write(m.d[i]);
   writeln;

end.

不等数列 (Dp插入e)

【题目描述】

将1到n任意排列,然后在排列的每两个数之间根据他们的大小关系插入“>”和“<”。问在所有排列中,有多少个排列恰好有k个“<”。答案对2012取模。

 

【输入格式】

第一行2个整数n,k。

 

【输出格式】

一个整数表示答案。

 

【样例输入】

5 2

【样例输出】

66

【数据范围】

对于30%的数据:n <= 10

对于100%的数据:k < n <= 1000,



F[i,j]=f[i-1,j](j+1)+f[i-1][j-1](i-j)   i表示从1到i的数   j表示小于号个数

          插入最大数e后添了一个>

          或者一个<的数量


const
   maxn=1000;
var
   f:array[0..1000,0..1000] of longint;
   n,i,j,k:longint;
begin
   assign(input,'num.in');
   assign(output,'num.out');
   reset(input);
   rewrite(output);
   read(n,k);
   if (k>n-1-k) then k:=n-1-k;
   for i:=1 to n do
   begin
      f[i,0]:=1;
      f[i,i-1]:=1;
   end;
   for i:=2 to n do
      for j:=1 to k do
         f[i,j]:=(f[i-1,j]*(j+1)+f[i-1,j-1]*(i-j)) mod 2012;
   writeln(f[i,k]);
   close(input);
   close(output);
end.

另附 暴搜%30数据的版本

var
   b:array[1..10] of boolean;
   f:array[0..10] of longint;
   n,k,i:longint;
procedure dfs(l,x,father:longint);
var
   i:longint;
begin
   if l=n then begin inc(f[x]); exit; end;
   for i:=1 to n do
   if not(b[i]) then
   begin
      b[i]:=true;
      if father<i then dfs(l+1,x+1,i) else
      dfs(l+1,x,i);
      b[i]:=false;
   end;

end;
begin
   readln(n,k);
   fillchar(b,sizeof(b),false);
   fillchar(f,sizeof(f),0);
   for i:=1 to n do
   begin
      b[i]:=true;
      dfs(1,0,i);
      b[i]:=false;
   end;
   for i:=0 to n-1 do write(f[i],' ');


end.

RQNOJ 658(观光公交)

几大注意点:

1.一次使用氦气加速器会把后面分成好几段。

2.我们仅维护end[i],wait[i]恒定,因此需提前让wait[i]=max(wait[i-1],wait[i]);

3.w[i]+w[i+1]+...+w[j],且w恒定,故可预处理sum[i](满足累加性)

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<string>
#include<algorithm>
#include<queue>
#include<functional>
#include<iostream>
#define MAXN 1000 +10
#define MAXM 10000 + 10
#define MAXK 100000 + 10
#define MAXD 100 + 10
#define MAXT 100000 + 10
using namespace std;
struct man
{
	int t,l,r;
}t[MAXM];
struct interval
{
	int l,r,w;
};

int n,m,k,ans,d[MAXN+1],wait[MAXN+1],w[MAXN+1],end[MAXN+1],sum[MAXN+1];
bool operator<(const interval a,const interval b)   //重载  operator < 的意思   为q做准备
{


	return a.w<b.w;
}

priority_queue<interval> q;   //priority_queue<Node, vector<Node>, greater<Node> >; 完整的不能用


void push(int l,int r)
{
	bool flag=0;
	for (int i=l;i<r;i++) if (d[i]) {flag=1;break;}
	if (!flag) return;
	int tot=sum[r]-sum[l];
	if (!tot) return ;
	interval now;
	now.w=tot;
	now.l=l;
	now.r=r;
	q.push(now);

//	 cout <<"add "<< now.l << ' ' << now.r <<' '<< now.w << endl;
}

int main()
{
//	freopen("qc.in","r",stdin);
	memset(wait,0,sizeof(wait));
	memset(w,0,sizeof(w));

	scanf("%d%d%d",&n,&m,&k);
	for (int i=1;i<=n-1;i++)
		scanf("%d",&d[i]);
	for (int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&t[i].t,&t[i].l,&t[i].r);
		wait[t[i].l]=max(wait[t[i].l],t[i].t);
		w[t[i].r]++;
	}
	end[1]=0;
	for (int i=2;i<=n;i++)
	   end[i]=max(end[i-1],wait[i-1])+d[i-1];
	ans=0;
	for (int i=1;i<=m;i++)
	   ans+=end[t[i].r]-t[i].t;

	sum[1]=sum[0]=0;
	for (int i=2;i<=n;i++) {sum[i]=sum[i-1]+w[i]; wait[i]=max(wait[i-1],wait[i]);}

//	for (int i=0;i<=n;i++) cout<<end[i]<<' ';
//	cout<<endl;


	int tot=d[1],head=1;
	for (int i=2;i<=n;i++)
	{
		if (wait[i]>=end[i])
		{
			if (tot) push(head,i);
			tot=0;
			head=i;
		}
		tot+=d[i];
		/*
		tot+=w[i]*min(1,d[i]);
//		tot+=w[i];
		*/
	}


	if (tot) push(head,n);


//00	cout<<ans<<endl;
	//贪心
//	sort(t+1,t+m+1,cmp);

// 调试
/*   while( !q.empty() ){
        cout << q.top().l << ' ' << q.top().r <<' '<< q.top().w << endl;
        q.pop();
	}
*/
/*
	for (int i=1;i<=n;i++)
	{
		cout<<end[i]<<' ';
	}
*/
	while (k&&!q.empty())
	{
/*	cout<<"/////////"<<endl;
	for (int i=1;i<=n;i++)
	{
		cout<<end[i]<<' ';
	}
	cout<<endl;
	for (int i=1;i<=n;i++)
	{
		cout<<wait[i]<<' ';
	}

	cout<<endl;
*/
		interval now=q.top();
		q.pop();
		ans-=now.w;
		int i=now.l;
//000
//     cout << now.l << ' ' << now.r <<' '<< now.w << endl;
//      cout << ans << endl;
//000


		while (!d[i]) i++;
		d[i]--;
		int head=i,tot=0,i2=0;
		i++;
		while (i<=now.r/*&&wait[i]<end[i]*/)
		{
		//	tot+=w[i-1];
			end[i]--;
			//000
//		    for (int cse=1;cse<=n;cse++) cout<<end[cse]<<',';
//			cout<<endl;
			//-
//			cout<<i<<endl;
//			cout<<wait[i+1]<<' '<<end[i+1]<<endl;
			if (wait[i]==end[i])
			    {push(head,i);head=i;}
			i++;
		}

		i--;
		if (head!=now.r) push(head,now.r);

/*
		if (i>now.r) {cout<<"smile"<<endl;
			cout<<'<'<<' '<<i<<' '<<wait[i]<<' '<<end[i]<<' '<<endl;}
*/
//		cout<<"i2:"<<i2<<endl;
/*		if (i2) i=i2;
		i--;
		push(head,i);
		if (i<now.r)
		{
//			if (!d[head]) tot+=w[head];
			push(i,now.r);
		}
*/

		//处理 end[i] 显然最多影响到 now.r
		k--;
	}

	cout<<ans<<'n';


// 调试
/*
	    while( !q.empty() ){
        cout << q.top().l << ' ' << q.top().r <<' '<< q.top().w << endl;
        q.pop();
	}
	for (int i=1;i<=n;i++)
	{
		cout<<end[i]<<' ';
	}



*/


//	while (1);

}

POJ 3661(贝茜晨练)

经典Dp,果断记忆化……

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<functional>
using namespace std;
#define MAXN 10000 + 10
#define MAXM 500 + 10
int f[MAXN][MAXM],n,m,d[MAXN];
int dfs(int i,int j)
{
	if (i==0) return 0;
	if (f[i][j]) return f[i][j];
	if (i&&!j) f[i][j]=dfs(i-1,0);
	if (j)
		 f[i][j]=dfs(i-1,j-1)+d[i];
	else
	{
		for (int k=min(i,m);k>0;k--)
		{
	          f[i][j]=max(f[i][j],dfs(i-k,k));
		}
	}
	return f[i][j];
}
int main()
{
//	freopen("running.in","r",stdin);
	memset(f,0,sizeof(f));
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++) scanf("%d",&d[i]);

	printf("%dn",dfs(n,0));

//	while (1);
	return 0;
}

POJ 3575(计算几何与二分-无尽的小数处理)

这题 写了将近半个月……总是在D各种Bug

总的说来-这题最难应该是在精度处理上

1

1

0 0 1

这组数据过了就说明精度处理差不多了……

Program kingdom;
const
   maxn=100;
   maxm=100;
   le=0.000000001;
type
   circle=record
            x,y,r:double;
          end;
var
   s:array[1..maxn,1..1000] of circle;
   n,i,j,k:longint;
   m:array[1..maxn] of longint;
   ans:array[1..maxn,1..4] of double;
   wanted:array[1..maxn] of double;
   b:array[1..maxn] of boolean;
   l,r:double;
function arccos(cosa:double):double;
var
   sina,tana:double;
begin
   if cosa=0 then exit(pi/2);

   sina:=sqrt(1-sqr(cosa));
   tana:=sina/cosa;
   exit(arctan(tana));

end;
function min(a,b:double):double;
begin
   if a<b then exit(a) else exit(b);
end;
function max(a,b:double):double;
begin
   if a>b then exit(a) else exit(b);
end;

function sector(a,r:double):double;
begin
   exit(a*r*r/2);
end;
function triangle(a,r:double):double;
begin
   exit(sin(a)*r*r/2);
end;
function inlside(s:circle;l:double):boolean;
begin
   if (s.x-s.r>l) or (abs(s.x-s.r-l)<le) then exit(true) else exit(false);
end;
function inrside(s:circle;r:double):boolean;
begin
   if (s.x+s.r<r) or (abs(s.x+s.r-r)<le) then exit(true) else exit(false);
end;


function intarea(s:circle;l,r:double):double;
var
   i,j:longint;
   a,a2,s1,s2,s3,s4:double;
   bl,br:boolean;
begin
   if (r<s.x-s.r) or (s.x+s.r<l) then exit(0);
   if (s.x<=l) then
   begin
      a:=arccos((l-s.x)/s.r)*2;
      if (abs(s.x-l)<le) then s1:=0
      else s1:=triangle(a,s.r);
      s2:=sector(a,s.r);


      if s.x+s.r>r then
      begin
         a:=arccos((r-s.x)/s.r)*2;
         s3:=sector(a,s.r);
         s4:=triangle(a,s.r);
         s2:=s2-(s3-s4);

      end;
      exit(s2-s1);
   end
   else
   if (s.x>=r) then
   begin
      a:=arccos((s.x-r)/s.r)*2;
      if (abs(s.x-r)<le) then s1:=0
      else s1:=triangle(a,s.r);
      s2:=sector(a,s.r);

      if s.x-s.r<l then
      begin
         a:=arccos((s.x-l)/s.r)*2;
         s3:=sector(a,s.r);
         s4:=triangle(a,s.r);
         s2:=s2-(s3-s4);


      end;
      exit(s2-s1);

   end
   else
   begin
      bl:=inlside(s,l);
      br:=inrside(s,r);
      if bl and br then exit(pi*s.r*s.r);
      if bl and not(br) then
      begin
         a:=arccos((r-s.x)/s.r)*2;
         s3:=sector(a,s.r)-triangle(a,s.r);
         exit(pi*s.r*s.r-s3);
      end;
      if not(bl) and br then
      begin
         a:=arccos((s.x-l)/s.r)*2;
         s3:=sector(a,s.r)-triangle(a,s.r);
         exit(pi*s.r*s.r-s3);
      end;



      a:=arccos((s.x-l)/s.r)*2;

      a2:=arccos((r-s.x)/s.r)*2;
      s1:=sector(2*pi-a-a2,s.r);
      s2:=triangle(a,s.r)+triangle(a2,s.r);
      exit(s1+s2);



   end;



end;
function place(k:longint;l,r:double):boolean;
var
   tot:double;
   i,j:longint;
begin
   tot:=0;
   for j:=1 to m[k] do
   begin
         tot:=tot+intarea(s[k,j],l,r);
   end;
//   writeln(tot*n,' ',wanted[k]*pi);

   if (abs(tot*n-wanted[k]*pi)<le) then exit(true);
   if (tot*n<(wanted[k]*pi)) then exit(false) else exit(true);
end;
function bsearch(r1,r2:double):double;
var
   m:double;
   i,j,k,num:longint;
   flag:boolean;
begin
   for k:=1 to 60 do
   begin
      flag:=false;
      m:=(r1+r2)/2;
      for i:=1 to n do
         if not b[i] then
         begin
            flag:=flag or place(i,l,m);
            if flag then
            begin
               num:=i;
               break;
            end;
         end;
      if flag then r2:=m else r1:=m;
   end;

   b[num]:=true;
   ans[num,1]:=l;
   ans[num,2]:=r1;

   exit(r1);


end;
begin
  { assign(input,'kingdom.in');
   reset(input);
  } r:=-10000;
   l:=10000;
   read(n);
   fillchar(b,sizeof(b),false);
   fillchar(wanted,sizeof(wanted),0);
   for i:=1 to n do
   begin
      read(m[i]);
      for j:=1 to m[i] do
      begin
         read(s[i,j].x,s[i,j].y,s[i,j].r);
 //        writeln(s[i,j].x,s[i,j].y,s[i,j].r);

         r:=max(r,s[i,j].x+s[i,j].r);
         l:=min(l,s[i,j].x-s[i,j].r);
         wanted[i]:=wanted[i]+sqr(s[i,j].r);

      end;
   end;
   r:=r+1;

   for i:=1 to n do
      l:=bsearch(l,r);

   for i:=1 to n do
   begin
      writeln('4');
      writeln(ans[i,1]:7:7,' 3000');
      writeln(ans[i,1]:7:7,' -3000');
      writeln(ans[i,2]:7:7,' -3000');
      writeln(ans[i,2]:7:7,' 3000');
   end;




//   close(input);
end.

拯救LongMM (递推公式求解)

拯救L o n g M M ( l a n . p a s / c / c p p )
【题目描述】
LongDD 将军为了平息延续数年战乱,决定释放战俘营中所有的俘虏。然而,
LongDD 将军不打算释放敌军的统帅LongMM——因为这个家伙异常聪明,是个难缠的
对手。所以LongDD 将军决定把LongMM 用链子固定到墙上。链子由n 个环组成,每
个环有可能在墙上,也可能不在墙上。
“LongDD 将军,你为什么把我绑在墙上,不让我获得自由”,LongMM 咆哮道。
“但是,LongMM,你并没有被绑在墙上。我很确定你可以自己把链子解开”,
LongDD 将军回答道,“但是请你在天黑之前解开,否则我会因为你制造噪音把你重
新抓起来。”
请帮助LongMM 吧!链子由n 个环组成,编号为1,2,…,n。我们可以把每个环从
墙上取下来或者从新放回墙上,但是需要遵循如下规则:
- 每一步只能取下或者装上一个环
- 编号为1 的环可以随意取下或装上
- 如果编号为1,…,k-1 的环都取下了,并且编号为k 的环在墙上,我们可
以随意取下或者装上第k+1 个环
- 当所有环都取下来之后,LongMM 可以逃脱了
给定每个环的初始状态,请你编写程序计算LongMM 最少需要多少步才能逃脱。
程序名: lan
【输入格式】
* 第 1 行: 有一个整数n,(1<=n<=1000),表示环的个数
* 第 2 行: 有n 个整数,第i 个整数O_i=0,表示第i 个环在初始的时候为摘下的
状态;如果O_i=1,表示第i 个环初始的时候为装在墙上的状态。
【输入样例】
4
1 0 1 0
【输出格式】
* 第 1 行: 只有一个整数,表示最少需要多少步才能让LongMM 逃脱。
【输出样例】
6
【输出解释】

先递推 

然后 找规律 发现从后往前 ans=2^jn-2^j(n-1)+2^j(n-2)+.....   (j[i]表示从左往右第i个1)

Program lan;
type
   arr=record
         len:longint;
         d:array[1..1000] of longint;
       end;
const
    F=1000000;
var
   n,i:longint;
   ans:arr;
   p2:array[1..1000] of arr;
   a:array[1..1001] of longint;
procedure multipy;
var
   i,j,k:longint;
begin
   for k:=2 to 1000 do
   begin
      p2[k].len:=p2[k-1].len;
      for i:=1 to p2[k-1].len do
      begin
         inc(p2[k].d[i],p2[k-1].d[i]*2);
         inc(p2[k].d[i+1],p2[k].d[i] div F);
         p2[k].d[i]:=p2[k].d[i] mod F;
      end;
      if p2[k].d[p2[k].len+1]<>0 then inc(p2[k].len);



   end;
   for k:=1 to 1000 do dec(p2[k].d[1]);




end;
function max(a,b:longint):longint;
begin
   if a>b then exit(a) else exit(b);
end;
Procedure add(a,b:arr;var c:arr);
var
   i,j:longint;
begin
   fillchar(c,sizeof(c),0);
   c.len:=max(a.len,b.len);
   for i:=1 to c.len do
   begin
      inc(c.d[i],a.d[i]+b.d[i]);
      inc(c.d[i+1],c.d[i] div F);
      c.d[i]:=c.d[i] mod F;
   end;
   if c.d[c.len+1]>0 then inc(c.len);




end;
procedure sub(a,b:arr;var c:arr);
var
   i,j:longint;
begin
   fillchar(c,sizeof(c),0);
   c.len:=max(a.len,b.len);
   for i:=1 to c.len do
   begin
      inc(c.d[i],a.d[i]-b.d[i]);
      if c.d[i]<0 then
      begin
         inc(c.d[i],F);
         dec(c.d[i+1],1);
      end;
   end;
   while (c.len>1) and (c.d[c.len]=0) do dec(c.len);


end;
Procedure work;
var
   i,j:longint;
   flag:boolean;
begin
   i:=n;
   flag:=true;
   while true do
   begin
      while (a[i]=0) and (i>1) do dec(i);
      if a[i]=0 then exit;
      if flag then add(ans,p2[i],ans)
      else sub(ans,p2[i],ans);

      dec(i);
      if i=0 then exit;
      flag:=not(flag);
   end;



end;
Procedure pri;
var
   i:longint;
begin
   write(ans.d[ans.len]);
   for i:=ans.len-1 downto 1 do
   begin
      if ans.d[i]<100000 then write('0');
      if ans.d[i]<10000 then write('0');
      if ans.d[i]<1000 then write('0');
      if ans.d[i]<100 then write('0');
      if ans.d[i]<10 then write('0');
      write(ans.d[i]);
   end;
   writeln;
end;

begin
   assign(input,'lan.in');
   assign(output,'lan.out');
   reset(input);
   rewrite(output);
   read(n);
   for i:=1 to n do read(a[i]);
   fillchar(ans,sizeof(ans),0);
   fillchar(p2,sizeof(p2),0);
   p2[1].len:=1;
   p2[1].d[1]:=2;
   multipy;
   work;
   pri;
   close(input);
   close(output);


end.

 

Monster (贪心)

Monster

【题目描述】

明明的手机上有这样一个游戏,有一排n个怪物,每个怪物的血量是mi。现在明明可以射出k个伤害均为p的火球射向某些怪物。当某个火球射到第i个怪物,除了这个怪物会掉血p以外,它左边的第j个怪物(j<=i),也会遭到Max(0, p - (i - j)* (i - j))的溅射伤害。当某个怪物的血量为负的时候,它就死了,但它的尸体已然存在,即其他怪物不会因为它死而改变位置。

明明想用这k 个火球消灭掉所有的怪物,但他同时希望每个火球的伤害p能尽可能的小,这样他才能完美过关。

【输入数据】

第一行两个数 nk (1≤ n ≤ 50000, 1 ≤ k ≤ 100000)。

第二行n个数m1m2,...mn (1 ≤ mi ≤ 109),表示每个怪物的生命值。

【输出数据】

最小的符合要求的p值。

【样例输入】

3 1

1 4 5

【样例输出】

6

【数据范围】

1 ≤ n ≤ 50000, 1 ≤ k ≤100000,1 ≤ mi ≤109

30%的数据,n ≤ 500

贪心+二分 显然 最右边那个妖怪一定是被轰击致死的

Program monster;
const
   INF=1000000000;
var
  n,k,i,j:longint;
  m1,a:array[1..50000] of longint;
procedure sort(l,r:longint);
var
   i,j,m,k2,kn:longint;
begin
   if l=r then
   begin
      writeln(l);
      close(input);
      close(output);
      halt;

   end;

   m:=(l+r) shr 1;
   for i:=1 to n do a[i]:=m1[i];
   k2:=k;
   for i:=n downto 1 do
      if a[i]>0 then
      begin
         kn:=k2;
         dec(k2,a[i] div m);
         a[i]:=a[i] mod m;
         if a[i]>0 then
         begin
            dec(k2);
            dec(a[i],m);
         end;

         if k2<0 then sort(m+1,r);
         kn:=kn-k2;
         j:=i-1;
         while (m-sqr(i-j)>0) and (j>=1) do
         begin
            if (kn*(a[j]-m+sqr(i-j))<0) then a[j]:=0 else
            dec(a[j],kn*(m-sqr(i-j)));
            dec(j);
         end;

      end;
   sort(l,m);


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

   read(n,k);
   for i:=1 to n do
   begin
      read(m1[i]);
      inc(m1[i]);
   end;


   sort(1,inf+1);


end.