切换到宽版
  • 11701阅读
  • 7回复

Milking Cows [复制链接]

上一主题 下一主题
离线stevenjl
 

只看楼主 倒序阅读 0 发表于: 2006-02-02

2.2 PROB Milking Cows

这题目,我浪费了多少时间啊!诶……
看看简单,调试啊……

TASK: milk2
LANG: PASCAL

Compiling...
Compile: OK

Executing...
sending data (milk2) milk2 /home/kolstad/trainweb

Test 1 OK [0.003 secs]
Test 2 OK [0.002 secs]
Test 3 OK [0.003 secs]
Test 4 OK [0.006 secs]
Test 5 OK [0.197 secs]
Test 6 OK [0.003 secs]
Test 7 OK [0.006 secs]
Test 8 OK [0.021 secs]

All tests OK.

Your program ('milk2') produced all correct answers!  This is your
submission #17 for this problem.  Congratulations!


Dream Walker...
离线blueblood
只看该作者 1 发表于: 2006-07-06
我一看到这个题目就想,有机会写线段树了(纯粹是为了学习线段树)以前没有找到这么明显的。但是有一个测试点不对。 不知是不是最后统计的时候错了
  1. #include <stdio.h>
  2. #define size 5000
  3. struct seg{
  4.    int b, e;
  5. };
  6. seg lres[size];
  7. int milk = 0;
  8. int nonmilk = 0;
  9. int lc = 0;
  10. int beg[size+1];
  11. int end[size+1];
  12. int l, r;
  13. class LineTree {
  14. private:
  15.     LineTree *left;
  16.     LineTree *right;
  17.     int cover, x, y;
  18.     void update();
  19. public:
  20.     long cl;
  21.     LineTree(int, int);
  22.     void init();
  23.     void insert(int, int);
  24.     void solve();
  25. };
  26. //cl表示测度的概念, cover表示覆盖到该区间的线段的个数
  27. void LineTree::update() {
  28.     if(cover > 0) {
  29.           cl = y - x;
  30.     } else if(y - x == 1) {
  31.           cl = 0;
  32.     } else {
  33.           cl = left->cl + right->cl;
  34.     }
  35. }
  36. LineTree::LineTree(int l, int r) {
  37.     x = l;
  38.     y = r;
  39.     left = right = NULL;
  40.        cl = cover = 0;
  41. }
  42. void LineTree::init() {
  43.     if(left != NULL) {
  44.           left->init();
  45.     }
  46.     cl = cover = 0;
  47.     if(right != NULL) {
  48.           right->init();
  49.     }
  50. }
  51. void LineTree::insert(int l, int r)
  52. {
  53.    if ( l >= x && l <= r )
  54.    {
  55.        if(cover > 0)
  56.        {
  57.            return;
  58.        }
  59.    }
  60.     if(l <= x && y <= r)
  61.        {
  62.            if ( y != x+1 && (left == NULL || right == NULL))
  63.            {    
  64.                left = new LineTree(x, (x+y)/2);
  65.                right = new LineTree((x+y)/2, y);
  66.                cl = cover = 0;
  67.            }
  68.         cover++;
  69.     }
  70.     else
  71.     {
  72.          if(left == NULL || right == NULL)
  73.          {
  74.                left = new LineTree(x, (x+y)/2);
  75.                right = new LineTree((x+y)/2, y);
  76.                cl = cover = 0;
  77.          }
  78.          
  79.         if(l < (x + y) / 2)
  80.         {
  81.           left->insert(l, r);
  82.         }
  83.         if(r > (x + y) / 2)
  84.         {
  85.           right->insert(l, r);
  86.         }
  87.     }
  88.     update();
  89. }
  90. //似乎很简洁
  91. void LineTree::solve()
  92. {
  93.    if(cover > 0)
  94.    {
  95.        lres[lc].b = x;
  96.        lres[lc++].e = y;
  97.    }
  98.    else
  99.    {
  100.        if (left != NULL)
  101.            left->solve();
  102.        if (right != NULL)
  103.            right->solve();
  104.    }
  105. }
  106. void cal()
  107. {
  108.    milk = lres[0].e - lres[0].b;
  109.    nonmilk = 0;
  110.    int t1 = lres[0].e - lres[0].b;
  111.    
  112.    for(int i=1; i<lc; i++)
  113.    {
  114.        if(lres[i-1].e != lres[i].b)
  115.        {
  116.            if (t1 > milk)
  117.                milk = t1;
  118.            t1 = 0;
  119.            if (nonmilk < (lres[i].b-lres[i-1].e) )
  120.                nonmilk = lres[i].b - lres[i-1].e;
  121.        }
  122.        else
  123.        {
  124.            t1 += lres[i].e - lres[i].b;
  125.        }
  126.    }
  127.    if (t1 > milk)
  128.        milk = t1;
  129.    if (lc > 1 && nonmilk < (lres[lc-1].b-lres[lc-2].e) )
  130.        nonmilk = lres[lc-1].b - lres[lc-2].e;
  131.        
  132.    printf("%d %d\n", milk, nonmilk);
  133. }
  134. int n;
  135. int main()
  136. {
  137.    freopen("milk2.in", "r", stdin);
  138.    freopen("milk2.out", "w", stdout);
  139.    scanf("%d", &n);
  140.    int nmax = 0, nmin = 1000000;
  141.    
  142.    for(int i=0; i<n; i++)
  143.    {
  144.        scanf("%d%d", &beg[i], &end[i]);
  145.        
  146.        if (beg[i] < nmin)
  147.            nmin = beg[i];
  148.        if (end[i] > nmax)
  149.            nmax = end[i];
  150.    }
  151.    l = nmin;
  152.    r = nmax;
  153.    LineTree root(l, r);
  154.    root.init();
  155.    
  156.    for(int j=0; j<n; j++)
  157.        root.insert(beg[j], end[j]);
  158.    
  159.    root.solve();
  160.    cal();
  161.    
  162.    return 0;
  163. }
离线stevenjl

只看该作者 2 发表于: 2006-07-06
C语言,看不懂啊~
Dream Walker...
离线网络虾客
只看该作者 3 发表于: 2006-11-05
很难吗?!我觉得非常简单啊!和NOIP2005普及第二题如出一辙
思路:这题和NOIP2005普及组的第二题很相似了。先开一个100 0002个空间的一维数组,然后初始化为N,然后一步步读入起始点和结束点,用s和e记录最小起始点和最大终止点。用for语句,把开始点+1(为什么要加一你就自己想想吧!)到结束点的时间段改为Y(如果已经是Y,那么重复写也不要紧啊!),然后最后数最长的一串Y和最长的一串N有多少个就是答案了!



参考源代码:
  1. #include<stdio.h>
  2. #define TIME 1000001
  3. int main()
  4. {
  5. long start,end,i,ans=0,total=0,s=TIME,e=0;
  6. char a[TIME];
  7. int person,j;
  8. memset(a,'N',TIME);
  9. FILE *in,*out;
  10. in=fopen("milk2.in","r");
  11. out=fopen("milk2.out","w");
  12. fscanf(in,"%d",&person);
  13. for(j=0;j<person;j++)
  14.   {
  15.     fscanf(in,"%ld %ld",&start,&end);
  16.     for(i=start+1;i<=end;i++)
  17.     a[i]='Y';
  18.     if(start<s) s=start;
  19.     if(end>e) e=end;
  20.   }
  21. for(i=s;i<=e+1;i++)
  22.   if(a[i]=='Y')
  23.   ans++;
  24.   else
  25.     {
  26.       if(ans>total)
  27.         total=ans;
  28.       ans=0;
  29.     }
  30. fprintf(out,"%ld ",total);
  31. total=0;
  32. ans=0;
  33. for(i=s+1;i<=e;i++)
  34.   if(a[i]=='N')
  35.   ans++;
  36.   else
  37.     {
  38.       if(ans>total)
  39.         total=ans;
  40.       ans=0;
  41.     }
  42. fprintf(out,"%ld\n",total);
  43. exit(0);
  44. }



Executing...
    Test 1: TEST OK [0.008 secs]
    Test 2: TEST OK [0.008 secs]
    Test 3: TEST OK [0.008 secs]
    Test 4: TEST OK [0.012 secs]
    Test 5: TEST OK [0.056 secs]
    Test 6: TEST OK [0.008 secs]
    Test 7: TEST OK [0.008 secs]
    Test 8: TEST OK [0.016 secs]
离线billoshi
只看该作者 4 发表于: 2007-03-28
没办法,用P的一个较优的算法(至少比开1000002数组的优)时间就是没有C/C++快啊。。。
P的编译器不行啊
离线gbbbb

只看该作者 5 发表于: 2007-11-03
用HASH,暴简单的
{
ID: wangxuan21
PROG: milk2
LANG: PASCAL
}

var n,i,j,t1,t2,max,min,p,q:longint;
    a:array[1..1000000]of boolean;
begin
assign(input,'milk2.in');
reset(input);
assign(output,'milk2.out');
rewrite(output);
read(n);
max:=0;
min:=maxlongint;
for i:=1 to 1000000 do
    a:=false;
for i:=1 to n do
    begin
    read(t1,t2);
    for j:=t1 to t2-1 do a[j]:=true;
    if max<t2-1 then max:=t2-1;
    if t1<min then min:=t1;
    end;
t1:=0; t2:=0;
p:=0; q:=0;
for i:=min to max do
    begin
    if a=true then
                  begin
                  if t2>q then q:=t2;
                  t2:=0;
                  inc(t1);
                  end;
    if a=false then
                  begin
                  if t1>p then p:=t1;
                  t1:=0;
                  inc(t2);
                  end;
    end;
if t1=0 then if t2>q then q:=t2;
if t2=0 then if t1>p then p:=t1;
writeln(p,' ',q);
close(input);
close(output);
end.
离线yonghu86cs
只看该作者 6 发表于: 2008-02-23
hen hao
只看该作者 7 发表于: 2008-04-06
{
ID: w1992072
PROG: milk2
LANG: PASCAL
}
PROGRAM milk2;
TYPE
arr=array[1..100000] of longint;
VAR
a1,a2:arr;
n,i,j,l,r,x1,x2:longint;

FUNCTION max(a,b:longint):longint;
begin
max:=a;
if b>a then max:=b;
end;

PROCEDURE qsort(var a:arr;l,r:longint);
var
x,t1,t2,i,j:longint;
begin
i:=l;j:=r;
x:=a;
repeat
  while (a<x) do inc(i);
  while (a[j]>x) do dec(j);
  if (i<=j) then
    begin
    t1:=a;a:=a[j];a[j]:=t1;
    t2:=a2;a2:=a2[j];a2[j]:=t2;
    inc(i);dec(j);
    end;
until i>j;
if (l<j) then qsort(a,l,j);
if (i<r) then qsort(a,i,r);
end;

BEGIN
assign(input, 'milk2.in');
reset(input);
assign(output, 'milk2.out');
rewrite(output);
readln(n);
for i:=1 to n do readln(a1,a2);
qsort(a1,1,n);
l:=a1[1];
r:=a2[1];
for i:=1 to n do
    begin
      if a1<=r then
        r:=max(a2,r)
      else begin
        x1:=max(x1,r-l);
        x2:=max(x2,a1-r);
        l:=a1;
        r:=a2;
      end;
    end;
    x1:=max(x1,r-l);
writeln(x1,' ',x2);
Close(input);
Close(output);
END.
快速回复
限100 字节
 
上一个 下一个