• 某模拟题题解 2016.11.17



      第一题并不是很难,首先筛出1 ~ sqrt(r)中的所有质数,然后用再用筛法直接筛[l, r]中的质数。筛出来找一遍就行了。

    Code

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cctype>
     4 #include<cstring>
     5 #include<cstdlib>
     6 #include<cmath>
     7 #include<sstream>
     8 #include<algorithm>
     9 #include<map>
    10 #include<set>
    11 #include<queue>
    12 #include<vector>
    13 #include<stack>
    14 using namespace std;
    15 typedef bool boolean;
    16 #define INF 0xfffffff
    17 #define smin(a, b) a = min(a, b)
    18 #define smax(a, b) a = max(a, b)
    19 template<typename T>
    20 inline void readInteger(T& u){
    21     char x;
    22     int aFlag = 1;
    23     while(!isdigit((x = getchar())) && x != '-');
    24     if(x == '-'){
    25         x = getchar();
    26         aFlag = -1;
    27     }
    28     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
    29     ungetc(x, stdin);
    30     u *= aFlag;
    31 }
    32 
    33 long long l, r;
    34 boolean isPrime[1000001];
    35 vector<int> p;
    36 
    37 inline void init(){
    38     readInteger(l);
    39     readInteger(r);
    40 }
    41 
    42 inline void getList(){
    43     int limit = (int)sqrt(r + 0.5);
    44     for(int i = 2; i <= limit; i++){
    45         if(!isPrime[i]){
    46             p.push_back(i);
    47             for(int j = i * i; j <= limit; j += i){
    48                 isPrime[j] = true;
    49             }
    50         }
    51     }
    52 }
    53 
    54 inline void solve(){
    55     int result = 0;
    56     memset(isPrime, 0, sizeof(isPrime));
    57     for(int i = 0; i < (signed)p.size(); i++){
    58         int pri = p[i];
    59         int bot = l / pri;
    60         for(int j = bot; j * 1LL * pri <= r; j++){
    61             long long val = j * 1LL * pri;
    62             if(val >= l && val != pri){
    63                 isPrime[val - l] = true;
    64             }
    65         }
    66     }
    67     for(int i = 0; i <= r - l; i++){
    68         if(!isPrime[i] && i + l != 1)    result++;
    69     }
    70     printf("%d", result);
    71 }
    72 
    73 int main(){
    74     freopen("prime.in", "r", stdin);
    75     freopen("prime.out", "w", stdout);
    76     init();
    77     getList();
    78     solve();
    79     return 0;
    80 }


      这道题就是道计算题(呵呵)。可以直接算出当n = 9, 99, 999...的情况。那么就可以从高位向低位计算。举个例子应该更好说明。
      例如n = 1234的时候,首位3,那么1到1000时的各位数字之和为1 * sum3 + (234 + 1) * 1 + 1 * 103,1001到1200的各位数字之和为2 * sum2 + (34 + 1) * 2 + (1 + 2) * 102,大概就是像这样的,继续算下去,然后累加起来就是答案。
      关于sum的递推式还是写一下吧sumi = sumi - 1 * 10 + 45 * 10i - 1

    Code

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cctype>
     4 #include<cstring>
     5 #include<cstdlib>
     6 #include<cmath>
     7 #include<sstream>
     8 #include<algorithm>
     9 #include<map>
    10 #include<set>
    11 #include<queue>
    12 #include<vector>
    13 #include<stack>
    14 using namespace std;
    15 typedef bool boolean;
    16 #define INF 0xfffffff
    17 #define smin(a, b) a = min(a, b)
    18 #define smax(a, b) a = max(a, b)
    19 template<typename T>
    20 inline void readInteger(T& u){
    21     char x;
    22     long long aFlag = 1;
    23     while(!isdigit((x = getchar())) && x != '-');
    24     if(x == '-'){
    25         x = getchar();
    26         aFlag = -1;
    27     }
    28     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
    29     ungetc(x, stdin);
    30     u *= aFlag;
    31 }
    32 
    33 template<typename T>
    34 inline void putInteger(T u){
    35     if(u == 0){
    36         putchar('0');
    37         return;
    38     }
    39     if(u < 0){
    40         putchar('-');
    41         u *= -1;
    42     }
    43     stack<char>    s;
    44     while(u != 0)    s.push(u % 10 + '0'), u /= 10;
    45     while(!s.empty())    putchar(s.top()), s.pop();
    46 }
    47 
    48 long long n;
    49 long long rn;
    50 long long bit;
    51 long long power[10] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
    52 
    53 inline void init(){
    54     readInteger(n);
    55     long long c = n;
    56     queue<long long> s;
    57     while(c != 0)    s.push(c % 10), c /= 10;
    58     while(!s.empty())
    59         rn *= 10, rn += s.front(), s.pop(), bit++;
    60 }
    61 
    62 long long sum[10];
    63 inline void getList(){
    64     sum[0] = 0;
    65     for(long long i = 1; i <= 9; i++)
    66         sum[i] = sum[i - 1] * 10 + 45LL * power[i - 1];
    67 }
    68     
    69 inline void solve(){
    70     long long result = 0;
    71     while(rn != 0){
    72         long long f = rn % 10;
    73         result += f * (n % power[bit - 1] + 1) + f * (f - 1) / 2 * power[bit - 1];
    74         result += f * sum[bit - 1];
    75         rn /= 10, bit--;
    76     }
    77     putInteger(result);
    78 }
    79 
    80 int main(){
    81     freopen("count.in", "r", stdin);
    82     freopen("count.out", "w", stdout);
    83     init();
    84     getList();
    85     solve();
    86     return 0;
    87 }


      这题正解线段树 + 扫描线。

      首先说说按列处理。车按照横坐标排序,矩形按照纵坐标排序,从1到n开始扫描。

    • 当扫描到一个车,加入按照纵坐标建的线段树,直接将对应点的值改为它的横坐标
    • 当扫描到某一个矩形的右边那条边,在线段树中查找[y1, y2]的区间最小值,当找到的结果小于x1,则说明存在一行不存在车

      然后再按行处理一次,思路几乎是一样的。至于判定, 如果两次扫描都不是完全覆盖, 那么输出NO,否则输出YES

    Code

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cctype>
      4 #include<cstring>
      5 #include<cstdlib>
      6 #include<cmath>
      7 #include<sstream>
      8 #include<algorithm>
      9 #include<map>
     10 #include<set>
     11 #include<queue>
     12 #include<vector>
     13 #include<stack>
     14 using namespace std;
     15 typedef bool boolean;
     16 #define INF 0xfffffff
     17 #define smin(a, b) a = min(a, b)
     18 #define smax(a, b) a = max(a, b)
     19 template<typename T>
     20 inline void readInteger(T& u){
     21     char x;
     22     long long aFlag = 1;
     23     while(!isdigit((x = getchar())) && x != '-');
     24     if(x == '-'){
     25         x = getchar();
     26         aFlag = -1;
     27     }
     28     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
     29     ungetc(x, stdin);
     30     u *= aFlag;
     31 }
     32 
     33 typedef class TreeNode{
     34     public:
     35         int from;
     36         int end;
     37         TreeNode* left;
     38         TreeNode* right;
     39         int minv;
     40         TreeNode(int from, int end):from(from), end(end), left(NULL), right(NULL), minv(-1){    }
     41 }TreeNode;
     42 
     43 typedef class SegTree {
     44     public:
     45         TreeNode* root;
     46         SegTree():root(NULL){    }
     47         SegTree(int s){
     48             build(root, 1, s);
     49         }
     50         void pushUp(TreeNode* node){
     51             node->minv = min(node->left->minv, node->right->minv);
     52         }
     53         void build(TreeNode* &node, int l, int r){
     54             node = new TreeNode(l, r);
     55             if(l == r)    return;
     56             int mid = (l + r) >> 1;
     57             build(node->left, l, mid);
     58             build(node->right, mid + 1, r);
     59         }
     60         void update(TreeNode* node, int d, int val){
     61             if(node->from == d && node->end == d){
     62                 node->minv = val;
     63                 return;
     64             }
     65             int mid = (node->from + node->end) >> 1;
     66             if(d <= mid)    update(node->left, d, val);
     67             else update(node->right, d, val);
     68             pushUp(node);
     69         }
     70         int query(TreeNode* node, int l, int r){
     71             if(node->from == l && node->end == r){
     72                 return node->minv;
     73             }
     74             int mid = (node->from + node->end) >> 1;
     75             if(l > mid)        return query(node->right, l, r);
     76             else if(r <= mid)    return query(node->left, l, r);
     77             else    return min(query(node->left, l, mid), 
     78                         query(node->right, mid + 1, r));
     79         }
     80         void clean(TreeNode* node){
     81             if(node == NULL)    return;
     82             clean(node->left);
     83             clean(node->right);
     84             delete node;
     85         } 
     86 }SegTree;
     87 
     88 typedef class Point {
     89     public:
     90         int x;
     91         int y;
     92         Point(const int x = 0, const int y = 0):x(x), y(y){        }
     93 }Point;
     94 
     95 typedef class Rect {
     96     public:
     97         int x1, x2;
     98         int y1, y2;
     99         int id;
    100         Rect(const int x1 = 0, const int y1 = 0, const int x2 = 0, const int y2 = 0):x1(x1), y1(y1), x2(x2), y2(y2), id(0){}
    101 }Rect;
    102 
    103 int n, m, k, q;
    104 SegTree lines;
    105 SegTree rows;
    106 Rect* rs;
    107 Point* ps;
    108 
    109 boolean cmpp1(const Point& a, const Point& b){
    110     if(a.x != b.x)    return a.x < b.x;
    111     return a.y < b.y;    
    112 }
    113 
    114 boolean cmpp2(const Point& a, const Point& b){
    115     if(a.y != b.y)    return a.y < b.y;
    116     return a.x < b.x;
    117 }
    118 
    119 boolean cmpr1(const Rect& a, const Rect& b){
    120     return a.x2 < b.x2;
    121 }
    122 
    123 boolean cmpr2(const Rect& a, const Rect& b){
    124     return a.y2 < b.y2;
    125 }
    126 
    127 inline void init(){
    128     readInteger(n);
    129     readInteger(m);
    130     readInteger(k);
    131     readInteger(q);
    132     ps = new Point[(const int)(k + 1)];
    133     rs = new Rect[(const int)(q + 1)];
    134     for(int i = 1; i <= k; i++){
    135         readInteger(ps[i].x);
    136         readInteger(ps[i].y);
    137     }
    138     for(int i = 1; i <= q; i++){
    139         readInteger(rs[i].x1);
    140         readInteger(rs[i].y1);
    141         readInteger(rs[i].x2);
    142         readInteger(rs[i].y2);
    143         rs[i].id = i;
    144     }
    145 }
    146 
    147 boolean *isProtected;
    148 
    149 inline void solve_lines(){
    150     isProtected = new boolean[(const int)(q + 1)];
    151     memset(isProtected, true, sizeof(boolean) * (q + 1));
    152     sort(ps + 1, ps + k + 1, cmpp1);
    153     sort(rs + 1, rs + q + 1, cmpr1);
    154     lines = SegTree(m);
    155     int kp = 1, kr = 1;
    156     for(int i = 1; i <= n; i++){
    157         while(ps[kp].x == i){
    158             lines.update(lines.root, ps[kp].y, ps[kp].x);
    159             kp++;
    160         }
    161         while(rs[kr].x2 == i){
    162             int fx = lines.query(lines.root, rs[kr].y1, rs[kr].y2);
    163             if(fx < rs[kr].x1)    isProtected[rs[kr].id] = false;
    164             kr++;
    165         }
    166     }
    167     lines.clean(lines.root);
    168 }
    169 
    170 inline void solve_rows(){
    171     sort(ps + 1, ps + k + 1, cmpp2);
    172     sort(rs + 1, rs + q + 1, cmpr2);
    173     rows = SegTree(n);
    174     int kp = 1, kr = 1;
    175     for(int i = 1; i <= m; i++){
    176         while(ps[kp].y == i){
    177             rows.update(rows.root, ps[kp].x, ps[kp].y);
    178             kp++;    
    179         }
    180         while(rs[kr].y2 == i){
    181             if(!isProtected[rs[kr].id]){
    182                 int fy = rows.query(rows.root, rs[kr].x1, rs[kr].x2);
    183                 if(fy >= rs[kr].y1)    isProtected[rs[kr].id] = true;
    184             }
    185             kr++;
    186         }
    187     }
    188 }
    189 
    190 const char str[2][10] = {"NO
    ", "YES
    "};
    191 inline void print(){
    192     for(int i = 1; i <= q; i++){
    193         printf("%s", str[isProtected[i]]);
    194     }
    195 }
    196 
    197 int main(){
    198     freopen("brother.in", "r", stdin);
    199     freopen("brother.out", "w", stdout);
    200     init();
    201     solve_lines();
    202     solve_rows();
    203     print();
    204     return 0;
    205 }
  • 相关阅读:
    堪称为经典游戏设计帖整理20个点击回复超高的精品贴
    【专题报道】Google I/O开发者大会
    android用户界面之AlarmManager教程实例汇
    Android2.2 API 中文文档系列
    ruby设计模式之【观察者】模式2————更加一般化的观察者模式
    ruby中require和load的区别
    ruby/python/java全覆盖的SeleniumWebdriver系列教程(1)————快速开始
    ruby + nokogiri实现将天涯易读全帖转换成txt文件的功能
    WatirWebdriver与watir1.x的差异
    Notepad++ 的一些常用快捷键
  • 原文地址:https://www.cnblogs.com/yyf0309/p/6075201.html
Copyright © 2020-2023  润新知