zoukankan      html  css  js  c++  java
  • BestCoder 1st Anniversary 1002-1005

    1002 Hidden String

    这个题怎么暴力怎么搞就好了. 可以枚举最长匹配前缀, 和最长匹配后缀, 中间暴力for.

     1 /*Author :usedrose  */
     2 /*Created Time :2015/7/25 19:05:28*/
     3 /*File Name :2.cpp*/
     4 #include <cstdio>
     5 #include <iostream>
     6 #include <algorithm>
     7 #include <sstream>
     8 #include <cstdlib>
     9 #include <cstring>
    10 #include <climits>
    11 #include <vector>
    12 #include <string>
    13 #include <ctime>
    14 #include <cmath>
    15 #include <deque>
    16 #include <queue>
    17 #include <stack>
    18 #include <set>
    19 #include <map>
    20 #define INF 0x3f3f3f3f
    21 #define eps 1e-8
    22 #define pi acos(-1.0)
    23 #define MAXN 1110
    24 #define OK cout << "ok" << endl;
    25 #define o(a) cout << #a << " = " << a << endl
    26 #define o1(a,b) cout << #a << " = " << a << "  " << #b << " = " << b << endl
    27 using namespace std;
    28 typedef long long LL;
    29 
    30 int T;
    31 string s;
    32 string t = "anniversary";
    33 
    34 int main()
    35 {
    36     
    37     cin >> T;
    38     while (T--) {
    39         cin >> s;
    40         string a, b, c;
    41         for (int i = 1;i < 11;++ i) 
    42             for (int j = 1;i + j < 11; ++ j) {
    43                 a = t.substr(0, i);
    44                 b = t.substr(i,j);
    45                 c = t.substr(i+j);
    46                 //cout << a << "!" << b << "!" << c << endl; 
    47                 if (a == "" || b == "" || c == "") continue;
    48                 int pos1, pos2, pos3;
    49                 pos1 = s.find(a);
    50                 while (pos1 != -1) {
    51                     pos2 = s.find(b, pos1+ a.length());
    52                     while (pos2 != -1) {
    53                         pos3 = s.find(c, pos2 +b.length());
    54                         if (pos3 != -1) {
    55                             cout << "YES" << endl;
    56                             goto en;
    57                         }
    58                         pos2 = s.find(b, pos2 + 1);
    59                         if (pos2 == -1) break;
    60                     }
    61                     pos1 = s.find(a,pos1 + 1);
    62                     if (pos1 == -1) break;
    63                 }
    64             }
    65          cout << "NO" << endl;   
    66 en:;        
    67     }
    68     return 0;
    69 }
    View Code



    1003 Sequence

    这个题看上去是一个贪心, 但是这个贪心显然是错的.
    事实上这道题目很简单, 先判断1个是否可以, 然后判断2个是否可以. 之后找到最小的k(k>2), 使得(m−k)mod6=0即可.

    证明如下:
    3n(n−1)+1=6(n∗(n−1)/2)+1, 注意到n∗(n−1)/2是三角形数, 任意一个自然数最多只需要3个三角形数即可表示. 枚举需要k个, 那么显然m=6(k个三角形数的和)+k, 由于k≥3, 只要m−k是6的倍数就一定是有解的.

    事实上, 打个表应该也能发现规律.

     1 /*Author :usedrose  */
     2 /*Created Time :2015/7/26 16:12:43*/
     3 /*File Name :2.cpp*/
     4 #include <cstdio>
     5 #include <iostream>
     6 #include <algorithm>
     7 #include <sstream>
     8 #include <cstdlib>
     9 #include <cstring>
    10 #include <climits>
    11 #include <vector>
    12 #include <string>
    13 #include <ctime>
    14 #include <cmath>
    15 #include <deque>
    16 #include <queue>
    17 #include <stack>
    18 #include <set>
    19 #include <map>
    20 #define INF 0x3f3f3f3f
    21 #define eps 1e-8
    22 #define pi acos(-1.0)
    23 #define MAXN 20110
    24 #define OK cout << "ok" << endl;
    25 #define o(a) cout << #a << " = " << a << endl
    26 #define o1(a,b) cout << #a << " = " << a << "  " << #b << " = " << b << endl
    27 using namespace std;
    28 typedef long long LL;
    29 
    30 
    31 int a[MAXN];
    32 int n, x;
    33 
    34 void init()
    35 {
    36     for (int i = 1;i <= 20000; ++ i)
    37         a[i] = 3*i*(i-1) + 1;
    38 }
    39 
    40 inline bool ok1(int x)
    41 {
    42     int pos = lower_bound(a, a + 2000, x) - a;
    43     if (a[pos] == x) return 1;
    44     return 0;
    45 }
    46 
    47 bool ok2(int x) 
    48 {
    49      for(int i=1,j=20000; i <  20000 &&a[i] < x;i++){
    50         while(j > 0 && a[i] + a[j] > x){
    51             j--;
    52         }
    53         if(j > 0 && a[i]+a[j] == x){
    54             return true;
    55         }
    56     }
    57     return false;
    58 }
    59 
    60 int main()
    61 {
    62     init();
    63     scanf("%d", &n);
    64     while (n--) {
    65         scanf("%d", &x);
    66         if (ok1(x)) puts("1");
    67         else if (ok2(x)) puts("2");
    68         else {
    69             for (int i = 3;i < 10; ++ i)
    70                 if ((x - i)% 6 == 0){
    71                     printf("%d
    ", i);
    72                     break;
    73                 }
    74         }
    75     }    
    76     return 0;
    77 }
    View Code


    1004 Bipartite Graph

    首先二分图可以分成两类点X和Y, 完全二分图的边数就是|X|⋅|Y|.我们的目的是max{|X|⋅|Y|}, 并且|X|+|Y|=n.

    把原图黑白染色, 每个联通块有ai个黑点, bi个白点, 于是就是要确定ai属于X还是属于Y. 然后我们考虑dp, dpi,x表示用了前i个联通块, |X|=x是否可行. dp方程很容易确定, dpi,x=dpi−1,x−a[i] or dpi−1,x−b[i].

    直接暴力是O(n2)的, 可以考虑用bitset优化, 这样就可以过了. 实际上由于数据很难造, 一些稍加优化的n2也可以过的

    1005 Happy King

    出题人的做法是点分治, 比赛的时候有人排序之后用lct维护单调性过了.

    设分治中心为g, 我们只需要计算跨过g的答案, 其他的可以分治计算.

    跨过根的可以容斥做, 没有限制的 - ∑端点落在同一颗子树上的. 上述两个过程是一样的, 于是只考虑没有限制的怎么做.

    令xi,yi为i到g路径上的最大值和最小值. 我们按照xi排序, 然后枚举xi必选, 那么前面可选的xj,yj(j<i)必须要满足xi−d≤xj,xi−d≤yj, 由于xj≥yj, 只需要考虑xi−d≤yj. 于是只要枚举xi然后用树状数组统计答案即可. 复杂度是O(nlog2n).

    事实上也是存在O(nlogn)的点分治做法, 分治时每次把树差不多分成两半, 就可以利用单调性, 用单调队列维护答案. 做法和POI2010 Pilots类似. 这个做法在比赛开始后Claris想到的.

  • 相关阅读:
    flutter之正则
    Flutter:Slivers大家族,让滑动视图的组合变得很简单!
    flutter之添加阴影
    flutter之https://www.jianshu.com/p/594a327267dc
    mac os下vscode快捷键
    detached HEAD解决办法
    flutter如何使用配置文件pubspec.yaml(位于项目根目录)来管理第三方依赖包
    flutter Route路由基本用法
    更新操作 关于json字符串的拼接、json字符串与json对象之间的转换
    做筛选遍历时遇到的json字符串、json对象、json数组 三者之间的转换问题
  • 原文地址:https://www.cnblogs.com/usedrosee/p/4678030.html
Copyright © 2011-2022 走看看