zoukankan      html  css  js  c++  java
  • 解题报告 poj 1486

     

    1.        题目  POJ 1486

    Description

    Professor Clumsey is going to give an important talk this afternoon. Unfortunately, he is not a very tidy person and has put all his transparencies on one big heap. Before giving the talk, he has to sort the slides. Being a kind of minimalist, he wants to do this with the minimum amount of work possible.

    The situation is like this. The slides all have numbers written on them according to their order in the talk. Since the slides lie on each other and are transparent, one cannot see on which slide each number is written.

     


    Well, one cannot see on which slide a number is written, but one may deduce which numbers are written on which slides. If we label the slides which characters A, B, C, ... as in the figure above, it is obvious that D has number 3, B has number 1, C number 2 and A number 4.

    Your task, should you choose to accept it, is to write a program that automates this process.

    Input

    The input consists of several heap descriptions. Each heap descriptions starts with a line containing a single integer n, the number of slides in the heap. The following n lines contain four integers xmin, xmax, ymin and ymax, each, the bounding coordinates of the slides. The slides will be labeled as A, B, C, ... in the order of the input.

    This is followed by n lines containing two integers each, the x- and y-coordinates of the n numbers printed on the slides. The first coordinate pair will be for number 1, the next pair for 2, etc. No number will lie on a slide boundary.

    The input is terminated by a heap description starting with n = 0, which should not be processed.

    Output

    For each heap description in the input first output its number. Then print a series of all the slides whose numbers can be uniquely determined from the input. Order the pairs by their letter identifier.

    If no matchings can be determined from the input, just print the word none on a line by itself.

    Output a blank line after each test case.

    Sample Input

    4
    6 22 10 20
    4 18 6 16
    8 20 2 18
    10 24 4 8
    9 15
    19 17
    11 7
    21 11
    2
    0 2 0 2
    0 2 0 2
    1 1
    1 1
    0

    Sample Output

    Heap 1
    (A,4) (B,1) (C,2) (D,3)
     
    Heap 2
    none

    Source

    Southwestern European Regional Contest 1998

     

    2.        题目实质

    言简意赅地说,就是求二分图匹配的必须边。

    3.        题目来源  poj

    4.        算法

    首先先跑一遍匈牙利算法,求二分图最大匹配,然后枚举着将匹配后的边删去,再接着跑匈牙利(也可用以匹配的边的一边进行增广,不能进行则是关键边),如果边数减少说明这是一个关键边,若果边数不减少说明不是,依此类推。

    但是,匈牙利算法 NOIP 不考,于是乎,另一种就应运而生了。

    遍历所有的矩形和数,看有没有一个矩形内只有一个数,或者一个数只属于一个矩形,这两种情况为可判断的情况,除这些之外的不确定,这个可用数学归纳法证明。然后每确定一种可确定的情况,就将这一个数和这一个矩形删去,依此类推。

    5.        注意事项

    第一种不好实现,第二种不太对还容易超时,恩恩。

    6.        程序代码

    第一种 Ray Pascal

    program lonely;

      var

        max,n,time,ans,i,j:longint;

        x1,x2,x3,y1,y2,y3,match,anss:array[0..100] of longint;

        a:array[0..100,0..100] of boolean;

        v:array[0..100] of boolean;

        ff:boolean;

      function dfs(s:longint):boolean;

        var

          i:longint;

        begin

          for i:=1 to n do

            begin

              if (not v[i])and(a[i,s]) then

                begin

                  v[i]:=true;

                  if (match[i]=0)or(dfs(match[i])) then

                    begin

                      match[i]:=s;

                      exit(true);

                    end;

                end;

            end;

          exit(false);

        end;

      function can(i,j:longint):boolean;

        begin

          if (x3[j]>=x1[i])and(x3[j]<=x2[i])and(y3[j]>=y1[i])and(y3[j]<=y2[i]) then exit(true);

          exit(false);

        end;

      begin

        assign(input,'slides.in');

        reset(input);

        assign(output,'slides.out');

        rewrite(output);

        readln(n);

        for i:=1 to n do

          readln(x1[i],x2[i],y1[i],y2[i]);

        for i:=1 to n do

          readln(x3[i],y3[i]);

        fillchar(a,sizeof(a),false);

        fillchar(match,sizeof(match),0);

        ans:=0;

        for i:=1 to n do

          for j:=1 to n do

            begin

              if can(i,j) then a[i,j+n]:=true;

            end;

        for i:=n+1 to n+n do

          begin

            fillchar(v,sizeof(v),false);

            if dfs(i) then inc(ans);

          end;

        max:=ans;

        anss:=match;

        ff:=false;

        for i:=1 to n do

          begin

            if anss[i]<>0 then

              begin

                a[i,anss[i]]:=false;

                ans:=0;

                fillchar(match,sizeof(match),0);

                for j:=n+1 to n+n do

                  begin

                    fillchar(v,sizeof(v),false);

                    if dfs(j) then inc(ans);

                  end;

                if (ans<max) then

                  begin

                    writeln(chr(i+64),' ',anss[i]-n);

                    ff:=true;

                  end;

                a[i,anss[i]]:=true;

              end;

          end;

        if not ff then write('None');

        close(input);

        close(output);

      end.

     

    第二种???(C++

    #include<stdio.h>
    #include<stdlib.h>
    struct rectangle{
           int data;
           int xmax;
           int xmin;
           int ymin;
           int ymax;
           int app;
           };
    struct dot{
           int isFound;
           int x;
           int y;
           int app;
           };
    void readRect(struct rectangle rect[],int n);
    void readDot(struct dot dot[],int n);
    int FindRect(struct rectangle rect[],struct dot dot[],int n);//返回拥有唯一数的矩形下标,如果没有则返回0;顺带就把这个矩形的data赋值,数的belon赋值;一旦找到一个就立即返回退出.
    int FindDot(struct rectangle rect[],struct dot dot[],int n);//返回只在一个矩形的数的下标,如果没有则返回0;顺带就把这个矩形的data赋值,数的belon赋值; 一旦找到一个就立即返回退出.
    int dotIn(struct rectangle rect,struct dot dot);
    int main()
    {
        int n,i,j,order=0,flag;
        struct rectangle rect[27];//rect,dot都是从1开始使用
        struct dot dot[27];
        scanf("%d",&n);
        while(n!=0)
        {
                   int temp1=-1,temp2;
                   order++;
                   flag=1;
                   readRect(rect,n);
                   readDot(dot,n);
                        for(i=1;i<=n;i++)
                        {
                                        
                                         if ((temp1=FindRect(rect,dot,n))==0&&(temp2=FindDot(rect,dot,n))==0) {
                                                                    printf("Heap %d\nnone\n",order);
                                                                    flag=0;
                                                                    break;
                                                                    }
                        }
                    printf("temp1==%d,temp2==%d\n",temp1,temp2);
                    if (flag==1){
                              printf("Heap %d\n",order);
                              for(i=1;i<=n;i++)
                              {
                                     if (rect[i].data!=0)
                                     printf("(%c,%d) ",'A'+i-1,rect[i].data);
                              }
                              printf("\n");
                              printf("\n");
                             }
                    scanf("%d",&n);
        }
        system("pause");
        return 0;
    }

    void readRect(struct rectangle rect[],int n)
    {
         int i;
         for(i=1;i<=n;i++)
         {
                          scanf("%d %d %d %d",&rect[i].xmin,&rect[i].xmax,&rect[i].ymin,&rect[i].ymax);
                          rect[i].data=0;
                          rect[i].app=0;
         }
    }

    void readDot(struct dot dot[],int n)
    {
         int i;
         for(i=1;i<=n;i++)
         {
                          scanf("%d %d",&dot[i].x,&dot[i].y);
                          dot[i].isFound=0;
                          dot[i].app=0;
         }
    }

    int FindRect(struct rectangle rect[],struct dot dot[],int n)//返回拥有唯一数的矩形下标,如果没有则返回0;顺带就把这个矩形的data赋值,数的belon赋值;一旦找到一个就立即返回退出.
    {
        int i,j;
        for(i=1;i<=n;i++)
        {
                         if (dot[i].isFound==0)
                         {
                                               int temp=0;
                                               dot[i].app=0;
                                               for(j=1;j<=n;j++)
                                               if ((rect[j].data==0)&&(dotIn(rect[j],dot[i])==1)){
                                                                                                 dot[i].app++;
                                                                                                 temp=j;
                                                                                                 }
                                               if (dot[i].app==1) {
                                                           rect[temp].data=i;
                                                           dot[i].isFound=1;
                                                           return i;
                                                           }
                         }
        }
        return 0;
    }

    int FindDot(struct rectangle rect[],struct dot dot[],int n)
    {
        int i,j;
        for(i=1;i<=n;i++)
        {
                         if (rect[i].data==0)
                         {
                                             int temp=0;
                                             rect[i].app=0;
                                             for(j=1;j<=n;j++)
                                             if ((dot[j].isFound==0)&&(dotIn(rect[i],dot[j])==1)){
                                                                                                  rect[i].app++;
                                                                                                  temp=j;
                                                                                                  }
                                             if (rect[i].app==1) {
                                                                 rect[i].data=temp;
                                                                 dot[temp].isFound=1;
                                                                 return i;
                                                                 }
                         }
        }
        return 0;
    }

    int dotIn(struct rectangle rect,struct dot dot)
    {
        if ((dot.x>rect.xmin)&&(dot.x<rect.xmax)&&(dot.y>rect.ymin)&&(dot.y<rect.ymax)) return 1;
        return 0;
    }

     

  • 相关阅读:
    Bootstrap
    Asp.Net母版页的相关知识
    连接Access数据库的连接字符串
    登录界面更换验证码图片
    .NET中string与StringBuilder在字符串拼接功能上的比较
    Asp.Net(C#)使用oleDbConnection 连接Excel
    非常规方法实现添加合并列
    ASP.Net页面间变量值传递的方法
    eclipse配置class注释模板
    spring中web.xml指定配置文件
  • 原文地址:https://www.cnblogs.com/SueMiller/p/2136343.html
Copyright © 2011-2022 走看看