• luogu【P2745】[USACO5.3]窗体面积Window Area


    这个题 就是个工程题然而一开始我并不知道怎么做。。还是看nocow的。。qwq)(原题入口

    算法为 离散化 + 扫描线  将大坐标变小  并且 用横纵坐标进行扫描 来计算面积

    一开始 我想边添加 点的坐标 边 离散  后来发现 有点问题 

    因为 它离散后的坐标 并不是按顺序来排(因为后来可能还加入中间的点 就需要重新离散)

    所以 我就把一开始的操作 和 坐标先存下来 进行离散 再进行操作 (QAQ 搞了好久

    后面 就是计算面积了 把一个大矩形 划分成 许多个小矩形 再进行标记 来计算面积了

    代码:

      1 #include <cstdio> 
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <cmath>
      5 #include <algorithm>
      6 #include <cctype>
      7 #include <iostream>
      8 #include <map>
      9 #include <vector>
     10 #define For(i, l, r) for(int i = (l); i <= (int)(r); ++i)
     11 #define Fordown(i, r, l) for(int i = (r); i >= (int)(l); --i)
     12 #define Set(a, v) memset(a, v, sizeof(a)) 
     13 #define pb push_back
     14 using namespace std;
     15 
     16 inline int read(){
     17   int x = 0, fh = 1; char ch;
     18   for(; !isdigit(ch); ch = getchar()) if (ch == '-') fh = -1;
     19   for(; isdigit(ch); ch = getchar()) x = (x<<1) + (x<<3) + (ch^'0');
     20   return x * fh;
     21 }
     22 
     23 const int N = 2550;
     24 map <int, int> fx, fy; //map数组 记录这个坐标是否被离散化过 
     25 int gx[1<<15], gy[1<<15]; //反向存储标号对应的坐标 
     26 int cnt_x = 0, cnt_y = 0, cnt = 0; //离散化的个数 
     27 char id[N]; //记录id数组 
     28 
     29 int now_deep = 2*(1<<15), top_deep = (1<<15), back_deep = 3*(1<<15);
     30 struct node {
     31     int xl, yl, xr, yr;
     32     int deep;  //层次 
     33     bool flag; //是否被删除 
     34 }; 
     35 node win[N]; //存储窗户 
     36 
     37 int idx(char ch) {
     38     For (i, 1, cnt) 
     39         if (id[i] == ch) return i;
     40     id[++cnt] = ch;
     41     return cnt;
     42 } //计算当前l的id 
     43 
     44 bool exist[N/2][N/2];
     45 double sum(int num) {
     46     if (!win[num].flag) return 0.0000; //如果已经删除 就返回0.0 (好像并没有用) 
     47     Set(exist, false); //判断小矩形是否存在 
     48     int sum_area = 0;
     49     int now_area = 0;
     50 
     51     For (i, win[num].xl, win[num].xr-1)
     52         For (j, win[num].yl, win[num].yr-1)
     53         {   exist[i][j] = true; //一开始置为真 
     54             sum_area += fabs ((gx[i+1] - gx[i] ) * (gy[j+1] - gy[j]) ) ; } //计算本来的总面积 
     55 
     56     For (i, 1, cnt) 
     57         if (win[i].flag && win[i].deep < win[num].deep) //如果在它上面 并且 未被删除 
     58             For (j, win[i].xl, win[i].xr-1)
     59                 For (k, win[i].yl, win[i].yr-1) 
     60                     exist[j][k] = false; //小矩形置为假 
     61     
     62     For (i, win[num].xl, win[num].xr-1)
     63         For (j, win[num].yl, win[num].yr-1)
     64             if (exist[i][j])  //存在 就加上
     65                 now_area += fabs( (gx[i] - gx[i+1]) * (gy[j] - gy[j+1]) ); //计算面积 
     66                 
     67     return ((double)now_area / (double)sum_area * 100.0000); //计算百分比 
     68 }
     69 
     70 struct oper {
     71     char opt;
     72     int l, xl, yl, xr, yr;
     73 };
     74 
     75 oper kk[N]; //存储操作 
     76 int cnt_op = 0;
     77 vector <int> tx; //存储坐标 
     78 vector <int> ty;
     79 
     80 int main(){
     81     freopen ("window.in", "r", stdin);
     82     freopen ("window.out", "w", stdout);
     83     char opt;
     84     while (scanf ("%c", &opt) != EOF) {
     85         char l; 
     86         int xl1, yl1, xr1, yr1;
     87         if (opt == 'w') { 
     88             scanf ("(%c,%d,%d,%d,%d)", &l, &xl1, &yl1, &xr1, &yr1);
     89             if (xl1 > xr1) swap(xl1, xr1);
     90             if (yl1 > yr1) swap(yl1, yr1); //左下角 和 右上角 
     91             kk[++cnt_op] = (oper) {opt, l, xl1, yl1, xr1, yr1};
     92             tx.pb (xl1); tx.pb(xr1); ty.pb(yl1); ty.pb(yr1);
     93         }
     94         else {
     95             scanf ("(%c)", &l);
     96             kk[++cnt_op] = (oper) {opt, l, 0, 0, 0, 0};
     97         }
     98     }
     99 
    100     sort (tx.begin(), tx.end() );
    101     For (i, 0, tx.size() - 1) 
    102         if (!fx[tx[i]] ) {fx[tx[i]] = ++cnt_x; gx[cnt_x] = tx[i]; }
    103     sort (ty.begin(), ty.end() );
    104     For (i, 0, ty.size() - 1)
    105         if (!fy[ty[i]] ) {fy[ty[i]] = ++cnt_y; gy[cnt_y] = ty[i]; }
    106     //运用map的离散化 可能有点慢 
    107 
    108     For (i, 1, cnt_op) {
    109         //cout << "id:  " << i << endl;
    110         opt = kk[i].opt;
    111         char l = kk[i].l; int num;
    112         int xl1 = kk[i].xl, yl1 = kk[i].yl, xr1 = kk[i].xr, yr1 = kk[i].yr;
    113         if (opt == 'w') {
    114             num = idx(l);
    115             win[num].xl = fx[xl1]; win[num].xr = fx[xr1];
    116             win[num].yl = fy[yl1]; win[num].yr = fy[yr1];
    117             win[num].flag = true; win[num].deep = --top_deep; //放在最上面 并将flag为真 
    118         } //创建一个新窗体(window)
    119         else if (opt == 't') {
    120             num = idx(l);
    121             win[num].deep = --top_deep;
    122         }//将窗体置顶(top)
    123         else if (opt == 'b') {
    124             num = idx(l);
    125             win[num].deep = ++back_deep;
    126         }//将窗体置底(back)
    127         else if (opt == 'd') {
    128             num = idx(l);
    129             win[num].flag = false;
    130         //    cout << num << endl;
    131         }//删除一个窗体(delete)
    132         else if (opt == 's') {
    133             num = idx(l);
    134             printf ("%.3lf
    ", sum(num));
    135         }//输出窗体可见部分的百分比(sum)
    136     }
    137 }
  • 相关阅读:
    从远程库克隆
    添加远程库
    远程仓库
    删除文件
    xml 解析的四种方式
    遍历Map
    Spring 和SpringMVC 的父子容器关系
    JDK各版本新特性!
    看啦这么就别人的博客 我也来写一篇! Object转换其他类型
    手机访问电脑搭建的服务器地址
  • 原文地址:https://www.cnblogs.com/zjp-shadow/p/7144579.html
Copyright © 2020-2023  润新知