Codeforces 611F New Year and Cleaning

来源:互联网 发布:金融信用信息基础数据库查询 编辑:程序博客网 时间:2024/04/29 15:33

传送门:http://codeforces.com/contest/611/problem/F
首先是局部到整体的转换,实际上本题目就是一个矩形在来回动,然后碰到边界后就会损失一行或者一列。
然后我本能的想法就是想通过矩形的面积去计算,然而这样是愚蠢的,应该通过每一行每一列移动的次数去计算最终答案,循环的次数可以通过两次模拟得到,第一次模拟可以得到矩形晃动的边界,为后续做铺垫。然后就可以得到每一行每一列的移动次数的序列,然后再实际模拟一遍给出序列(得到实际对应时刻每一行每一列的长度)即可得出答案
优点学习:
go_x的判断方法
loop的判断方法
还有add的方法,保证其取模的时候不会出问题

附上tourist 的代码:

#include <bits/stdc++.h>using namespace std;const int md = 1000000007;inline void add(int &a, int b) {  a += b;  if (a >= md) a -= md;}inline int mul(int a, int b) {  return (long long) a * b % md;}const int N = 2000010;int n;char s[N];vector <long long> get(char forw, char backw, int bound) {  vector <long long> res;  int x = 0, xl = 0, xr = 0;  for (int i = 0; i < n; i++) {    if (s[i] == forw) {      x++;      if (x > xr) {        xr = x;        res.push_back(i);      }    }    if (s[i] == backw) {      x--;      if (x < xl) {        xl = x;        res.push_back(i);      }    }  }  // loop ones?  {    vector <long long> loop;    for (int i = 0; i < n; i++) {      if (s[i] == forw) {        x++;        if (x > xr) {          xr = x;          loop.push_back(i);        }      }      if (s[i] == backw) {        x--;        if (x < xl) {          xl = x;          loop.push_back(i);        }      }    }    if (!loop.empty()) {      while (res.size() < bound) {        for (int i = 0; i < (int) loop.size(); i++) {          loop[i] += n;          res.push_back(loop[i]);        }      }    }  } // cout<<"forw="<<forw<<endl;        for (int i = 0; i < (int) res.size(); i++) {    res[i]++;  //  printf("res[%d]=%d \n",i,res[i]);  }  return res;}int main() {  int h, w;  scanf("%d %d %d", &n, &h, &w);  scanf("%s", s);  vector <long long> xs = get('R', 'L', w);  vector <long long> ys = get('U', 'D', h);  int xcnt = xs.size();  int ycnt = ys.size();  int xptr = 0;  int yptr = 0;  int ans = 0;  while (xptr < xcnt || yptr < ycnt) {    if (h == 0 || w == 0) {      break;    }    bool go_x = (yptr == ycnt || (xptr < xcnt && xs[xptr] < ys[yptr]));    if (go_x) {      add(ans, mul(h, xs[xptr] % md));      xptr++;      w--;    } else {      add(ans, mul(w, ys[yptr] % md));      yptr++;      h--;    }  }  if (h > 0 && w > 0) {    printf("%d\n", -1);    return 0;  }  printf("%d\n", ans);  return 0;}/*3 4 6 RRL*/
0 0