• 湖南2013第九届省赛解题报告(长期拖延更新中。。。)


    偶尔做一题,做一题更新一题好了。。。

    A、COJ1328: 近似回文词

    转化的时候记录每个字母在原串位置,对新串枚举中点,向两边枚举判近似回文,更新更长回文。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<stdlib.h>
     4 #include<ctype.h>
     5 const int maxn = 1011;
     6 char buf[maxn];
     7 char as[maxn];
     8 int p[maxn];
     9 int k;
    10 int main()
    11 {
    12     int i, j, start, maxlen, alen, neq, ca = 0;
    13     while(scanf("%d", &k) != EOF)
    14     {
    15         gets(buf);
    16         gets(buf);
    17         for(i = j = 0; buf[i]; i ++)
    18             if(isalpha(buf[i]))
    19             {
    20                 as[j] = tolower(buf[i]);
    21                 p[j] = i;
    22                 j ++;
    23             }
    24         as[j] = 0;
    25         alen = j;
    26         maxlen = 0;
    27         start = -1;
    28         for(i = 0; as[i]; i ++)
    29         {
    30             for(j = neq = 0; i - j >= 0 && i + j < alen; j ++)
    31             {
    32                 neq += as[i - j] != as[i + j];
    33                 if(neq > k) break;
    34             }
    35             j --;
    36             if(p[i + j] - p[i - j] + 1 > maxlen)
    37                 maxlen = p[i + j] - p[i - j] + 1, start = p[i - j];
    38             for(j = 1, neq = 0; i - j >= -1 && i + j < alen; j ++)
    39             {
    40                 neq += as[i - j + 1] != as[i + j];
    41                 if(neq > k) break;
    42             }
    43             j --;
    44             if(j <= 0) continue;
    45             if(p[i + j] - p[i - j + 1] + 1 > maxlen)
    46             {
    47                 maxlen = p[i + j] - p[i - j + 1] + 1, start = p[i - j + 1];
    48             }
    49         }
    50         printf("Case %d: %d %d
    ", ++ca, maxlen, start + 1);
    51     }
    52     return 0;
    53 }
    View Code

    B、COJ1329: 一行盒子

    构造双向链表,按要求进行一系列链接操作,对反转加一个标记即可。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<stdlib.h>
     4 #include<algorithm>
     5 using namespace std;
     6 const int maxn = 100111;
     7 int turn;
     8 struct Box
     9 {
    10     int lr[2];
    11 };
    12 Box b[maxn];
    13 int n, m, p, x, y;
    14 void init(int n)
    15 {
    16     turn = 0;
    17     b[0].lr[1] = 1;
    18     for(int i = 1; i <= n + 1; i ++)
    19         b[i].lr[0] = i - 1, b[i].lr[1] = i + 1;
    20 }
    21 int main()
    22 {
    23     int ca = 0;
    24     long long ans;
    25     while(scanf("%d%d", &n, &m) != EOF)
    26     {
    27         init(n);
    28         while(m --)
    29         {
    30             scanf("%d", &p);
    31             switch(p)
    32             {
    33                 case 1:
    34                     scanf("%d%d", &x, &y);
    35                     b[b[x].lr[turn]].lr[!turn] = b[x].lr[!turn];
    36                     b[b[x].lr[!turn]].lr[turn] = b[x].lr[turn];
    37                     b[x].lr[turn] = b[y].lr[turn];
    38                     b[x].lr[!turn] = y;
    39                     b[y].lr[turn] = x;
    40                     b[b[x].lr[turn]].lr[!turn] = x;
    41                     break;
    42                 case 2:
    43                     scanf("%d%d", &x, &y);
    44                     b[b[x].lr[turn]].lr[!turn] = b[x].lr[!turn];
    45                     b[b[x].lr[!turn]].lr[turn] = b[x].lr[turn];
    46                     b[x].lr[!turn] = b[y].lr[!turn];
    47                     b[x].lr[turn] = y;
    48                     b[y].lr[!turn] = x;
    49                     b[b[x].lr[!turn]].lr[turn] = x;
    50                     break;
    51                 case 3:
    52                     scanf("%d%d", &x, &y);
    53                     if(b[x].lr[turn] != y && b[x].lr[!turn] != y)
    54                     {
    55                         b[b[x].lr[turn]].lr[!turn] = y;
    56                         b[b[x].lr[!turn]].lr[turn] = y;
    57                         b[b[y].lr[turn]].lr[!turn] = x;
    58                         b[b[y].lr[!turn]].lr[turn] = x;
    59                         swap(b[x], b[y]);
    60                     }
    61                     else
    62                     {
    63                         if(b[x].lr[turn] == y) swap(x, y);
    64                         b[b[x].lr[turn]].lr[!turn] = y;
    65                         b[b[y].lr[!turn]].lr[turn] = x;
    66                         b[x].lr[!turn] = b[y].lr[!turn];
    67                         b[y].lr[turn] = b[x].lr[turn];
    68                         b[x].lr[turn] = y;
    69                         b[y].lr[!turn] = x;
    70                     }
    71                     break;
    72                 case 4:
    73                     turn  = !turn;
    74             }
    75         }
    76         ans = 0;
    77         int start, end, cnt;
    78         if(!turn) start = 0, end = n + 1;
    79         else start = n + 1, end = 0;
    80         cnt = 0;
    81         for(int i = start; i != end; i = b[i].lr[!turn], cnt ++)
    82         {
    83             if(cnt & 1) ans += i;
    84         }
    85         printf("Case %d: %lld
    ", ++ca, ans);
    86     }
    87     return 0;
    88 }
    View Code

    C、COJ1330: 字符识别?

    检查第四行星号的位置即可

     1 #include<stdio.h>
     2 int main()
     3 {
     4     char s[50];
     5     int i, n;
     6     while(scanf("%d", &n) != EOF)
     7     {
     8         for(i = 0; i < 4; i ++)
     9             scanf("%s", s);
    10         for(i = 0; i < (n << 2); i += 4)
    11         {
    12             if(s[i] == '*') printf("2");
    13             else if(s[i + 1] == '*') printf("1");
    14             else printf("3");
    15         }
    16         scanf("%s", s);
    17         printf("
    ");
    18     }
    19     return 0;
    20 }
    View Code

    E、COJ1332: 割耳法

    首先明确,1、任何对角线,是否可以切割,与切割的步骤无关。2、任何边和切割的线,都肯定是某个三角形的一条边。

    由此,预处理所有可切割的对角线,选一条边作为起始(p[0]~p[n-1]最合适,可保证start<end),其他的点与这条边可构成三角形。

    如果这条三角形除了p[start]~p[end]这条边之外的两条边都是可切割边(或者有一条是多边形的边),则可分割子问题。

    dp[start][end]表示p[start]~p[end]为起始边,与p[start~end]的这些点构成的多边形作为子问题切割之后的最优解。

    这样,转移方程为dp[start][end] = dp[start][i] + dp[i][end] + Dis(p[start], p[i]) + Dis(p[i], p[end]),而有一条边是多边形边的时候特别处理一下。

    另外判断是否为可切割对角线的时候,要注意1、对角线不与任何其他边规范相交。2、其他任何顶点不在对角线上。3、对角线不在多边形外部。

      1 #include<stdio.h>
      2 #include<stdlib.h>
      3 #include<string.h>
      4 #include<math.h>
      5 const int maxn = 111;
      6 const double eps = 1e-10;
      7 const double inf = 1e20;
      8 const double pi = acos(-1.0);
      9 inline double dcmp(double x){return (x > eps) - (x < -eps);}
     10 inline double min(double a, double b) {return a < b ? a : b;}
     11 inline double max(double a, double b) {return a > b ? a : b;}
     12 inline double Sqr(double x) {return x * x;}
     13 struct Point
     14 {
     15     double x, y;
     16     Point(){x = y = 0;}
     17     Point(double a, double b){x = a, y = b;}
     18     inline Point operator-(const Point &b)const
     19     {return Point(x - b.x, y - b.y);}
     20     inline Point operator+(const Point &b)const
     21     {return Point(x + b.x, y + b.y);}
     22     inline Point operator*(const double &b)const
     23     {return Point(x * b, y * b);}
     24     inline double Dis(const Point &b)const
     25     {return sqrt(Sqr(x - b.x) + Sqr(y - b.y));}
     26     inline double cross(const Point &b, const Point &c)const
     27     {return (b.x - x) * (c.y - y) - (c.x - x) * (b.y - y);}
     28     inline double dot(const Point &b)const
     29     {return x * b.x + y * b.y;}
     30     inline bool InLine(const Point &b, const Point &c)const
     31     {return !dcmp(cross(b, c));}
     32     inline bool OnSeg(const Point &b, const Point &c)const
     33     {return InLine(b, c) && (*this - c).dot(*this - b) < eps;}
     34     inline bool InSeg(const Point &b, const Point &c)const
     35     {return InLine(b, c) && (*this - c).dot(*this - b) < -eps;}
     36 };
     37 bool SegCross(const Point &a, const Point &b, const Point &c, const Point &d)
     38 {
     39     return dcmp(a.cross(b, c) * a.cross(b, d)) < 0 && dcmp(c.cross(d, a) * c.cross(d, b)) < 0;
     40 }
     41 Point p[maxn];
     42 int n;
     43 double dp[maxn][maxn];
     44 bool vis[maxn][maxn];
     45 bool cancut[maxn][maxn];
     46 double DPS(int start, int end)
     47 {
     48     double &ans = dp[start][end];
     49     if(vis[start][end]) return ans;
     50     vis[start][end] = true;
     51     if(end - start <= 2) return ans = 0;
     52     ans = inf;
     53     int i;
     54     if(cancut[start][end - 1])
     55         ans = min(ans, DPS(start, end - 1) + p[start].Dis(p[end - 1]));
     56     if(cancut[start + 1][end])
     57         ans = min(ans, DPS(start + 1, end) + p[start + 1].Dis(p[end]));
     58     for(i = start + 2; i < end - 1; i ++)
     59         if(cancut[start][i] && cancut[i][end])
     60             ans = min(ans, DPS(start, i) + DPS(i, end) + p[start].Dis(p[i]) + p[i].Dis(p[end]));
     61     return ans;
     62 }
     63 
     64 bool InSimplePolygon(Point u, Point p[], int n)
     65 {
     66   int flag = 0;
     67   for(int i = 0; i < n; i++)
     68   {
     69     Point p1 = p[i];
     70     Point p2 = p[(i+1)%n];
     71     if(u.OnSeg(p1, p2)) return false;
     72     int k = dcmp(p1.cross(p2, u));
     73     int d1 = dcmp(p1.y - u.y);
     74     int d2 = dcmp(p2.y - u.y);
     75     if(k > 0 && d1 <= 0 && d2 > 0) flag++;
     76     if(k < 0 && d2 <= 0 && d1 > 0) flag--;
     77   }
     78   return flag != 0;
     79 }
     80 void InitCanCut()
     81 {
     82     memset(cancut, 0, sizeof(cancut));
     83     for(int i = 0; i < n; i ++)
     84         for(int j = i + 2; j < n; j ++)
     85         {
     86             if(i == 0 && j == n - 1) continue;
     87             int k = n;
     88             for(k = 0; k < n; k ++)
     89             {
     90                 if(SegCross(p[i], p[j], p[k], p[k + 1]) || (k != i && k != j && p[k].InSeg(p[i], p[j])))
     91                     break;
     92             }
     93             if(k == n && InSimplePolygon((p[i] + p[j]) * 0.5, p, n)) cancut[i][j] = cancut[j][i] = true;
     94         }
     95 }
     96 
     97 int main()
     98 {
     99     int ca = 0;
    100     while(scanf("%d", &n) != EOF)
    101     {
    102         for(int i = 0; i < n; i ++)
    103             scanf("%lf%lf", &p[i].x, &p[i].y);
    104         p[n] = p[0];
    105         InitCanCut();
    106         memset(vis, 0, sizeof(vis));
    107         printf("Case %d: %.4f
    ", ++ca, DPS(0, n - 1));
    108     }
    109     return 0;
    110 }
    View Code
  • 相关阅读:
    坑爹的PostgreSQL的美元符号(有时需要替换成单引号)
    DataFrame的apply用法
    Pytorch写CNN
    Pytorch分类和准确性评估--基于FashionMNIST数据集
    设置Mac终端、pip、Anaconda、PyCharm共用一套环境
    Python编程基本规范
    【转】动态规划:最长递增子序列Longest Increasing Subsequence
    动态规划--找零钱
    在线编写复杂的数学公式--EdrawMath
    pandas如何逐行需改DataFrame
  • 原文地址:https://www.cnblogs.com/CSGrandeur/p/3391142.html
Copyright © 2020-2023  润新知