zoukankan      html  css  js  c++  java
  • UVA11134传说中的车(放棋子)

    题意:
          给你一个n*n的棋盘,让你在棋盘上放n个棋子,要求是所有棋子不能相互攻击(同行或者同列就会攻击),并且每个棋子都有一个限制,那就是必须在给定的矩形r[i]里,输出每个棋子的位置,special Jude。


    思路:
          看完后第一反应就是匈牙利(哎!惭愧啊。)结果想着怎么建图,想了一会呵呵了,果断想别的方法,其实这个题目设计到一个小思想非常好,那就是把整体分解,这个题目说的是什么?是每个棋子都限制了一个矩形范围,矩形范围又是什么?是不是就是xl<=x<=xr&&rl<=y<=yr,其实x和y我们可以分开考虑,可以分开的原因就是x和y之间没有限制因素,也不会相互影响,就像是中学时学的速度分解一样,这个就是这个题目的关键点,想到这个AC的可能性就很大了,分解后我们要处理的就是给你一些区间限制,然后在每个区间内都必须选择一个点放东西,最后要求同一个点不能放两个东西,也就是本题目的同一行或者一列不能放两个其子一样,然后就是贪心了,怎么贪心呢?我们可以把每个区间都按照右端点从小到大排序,然后我们从前往后贪心,右端点越小的“自由性”越小,所以要先处理,所以放在前面,对于每一断,我们就从这个段的做端点开始找,找第一个没被占用的点,占用上就行了,如果都找到右端点了还没找到可以用的点,那么就直接没解了,x和y都是这么处理的,找的时候我用的是set容器总的时间复杂度是O(n*log(n)),如果不想用set直接暴力找也应该不会超时,时间复杂度是O(n*n).




    #include<set>
    #include<stdio.h>
    #include<algorithm>


    #define N 5000 + 10


    using namespace std;


    typedef struct
    {
       int l ,r ,id;
    }EDGE;


    int AnsX[N] ,AnsY[N];
    EDGE X[N] ,Y[N];
    set<int>set1 ,set2;


    bool camp(EDGE a ,EDGE b)
    {
       return a.r < b.r;
    }


    int main ()
    {
       int i ,n;
       int x1 ,x2 ,y1 ,y2;
       while(~scanf("%d" ,&n) && n)
       {
          set1.clear() ,set2.clear();
          for(i = 1 ;i <= n ;i ++)
          {
             scanf("%d %d %d %d" ,&x1 ,&y1 ,&x2 ,&y2);
             X[i].l = x1 ,X[i].r = x2;
             Y[i].l = y1 ,Y[i].r = y2;
             X[i].id = Y[i].id = i;
             set1.insert(i);
             set2.insert(i);
          }
          set1.insert(10000000);
          set2.insert(10000000);
          sort(X + 1 ,X + n + 1 ,camp);
          sort(Y + 1 ,Y + n + 1 ,camp);
          int mk = 0;
          for(i = 1 ;i <= n && !mk ;i ++)
          {
             int tmpx = *set1.lower_bound(X[i].l);
             if(tmpx > X[i].r) mk = 1;
             AnsX[X[i].id] = tmpx;
             set1.erase(tmpx);
             
             int tmpy = *set2.lower_bound(Y[i].l);
             if(tmpy > Y[i].r) mk = 1;
             AnsY[Y[i].id] = tmpy;
             set2.erase(tmpy);
          }
          
          if(mk)
          {
             puts("IMPOSSIBLE");
             continue;
          }
          for(i = 1 ;i <= n ;i ++)
          printf("%d %d " ,AnsX[i] ,AnsY[i]);
       }
       return 0;
    }
       
          
          

  • 相关阅读:
    用c#小程序理解线程
    我对线程入门理解
    网站发布后IIS故障解决办法
    ASP .NET XML 文件
    SortedList 对象兼有 ArrayList 和 Hashtable 对象的特性。
    (笔记)索引器
    HOW TO:使用 Visual C# .NET 在 ASP.NET 中创建自定义错误报告
    读取EXCEL的数据到datagridview
    一个超级简单的文件流操作WINDOW应用程序
    Gridview事件
  • 原文地址:https://www.cnblogs.com/csnd/p/12062575.html
Copyright © 2011-2022 走看看