zoukankan      html  css  js  c++  java
  • ZOJ 2997 Black and White

      题目大意:给三个正整数n, p, q,判断是否存在这样一个长度为n的序列满足:(1)任何一个长度为p的连续子序列的和为正数;(2)任何一个长度为q的连续子序列的和为负数。如果存在这样一个序列,输出一个这样的序列。

      看到这个题目,没有什么想法,不会做...有一个广为流传的zoj题目列表,其中某大牛是这样分析的:

      经典的拓扑排序,构造一个长度为 N 的序列,使得序列所有连续 P 个元素之和为正,且所有连续 Q 个元素之和为负。将问题转化,构造这个序列的累加序列,相当于构造一个长度为 N + 1 的序列 S[0..N],满足 S[i+P] - S[i] > 0 S[i+Q] - S[i] < 0。这样的话,可以构造 N+1 顶点的图,将所有 S[i] > S[j] 的关系创建有向边 (i, j) 。那么,将这个图拓扑排序,然后如果有环,则不可构造,否则,其深搜弹出序号本身即可作为 S[i] 的值。

      看来自己分析问题、转换问题的能力还是好弱啊,还要继续努力啊...

      最开始用了一个G[5000][5000]的数组保存有向图,结果MLE,然后看别人代码,忽然发现没必要去存图,有规律的嘛(最初就没考虑5000*5000的数组会超过内存限制,一直再担心太多递归调用会导致栈溢出),就把G数组去掉了,然后神奇地过了,我还一直担心栈溢出呢,代码如下:

    View Code
     1 #include <cstdio>
     2 #include <cstring>
     3 
     4 const int maxn = 5000+10;
     5 int c[maxn];
     6 int n, p, q;
     7 int cnt;   //the number of    vertexes poped
     8 int ans[maxn];
     9 
    10 bool dfs(int u)
    11 {
    12     c[u] = -1;
    13     for(int v = 0; v <= n; v++)
    14         if((u - v == p) || (v - u == q))
    15         {
    16             if(c[v] < 0)   return false;
    17             else if(!c[v] && !dfs(v))   return false;
    18         }
    19     c[u] = 1;
    20     ans[u] = ++cnt;
    21     return true;
    22 }
    23 
    24 bool toposort()
    25 {
    26     for(int u = 0; u <= n; u++)
    27         if(!c[u])
    28             if(!dfs(u))   return false;
    29     return true;
    30 }
    31 
    32 int main()
    33 {
    34 #ifdef LOCAL
    35     freopen("in", "r", stdin);
    36 #endif
    37     while(scanf("%d%d%d", &n, &p, &q) != EOF)
    38     {    
    39         memset(c, 0, sizeof(c));
    40         cnt = 0;
    41         if(toposort())
    42         {
    43             printf("YES\n");
    44             for(int i = 1; i <= n; i++)
    45             {
    46                 printf("%s", i == 1 ? "" : " ");
    47                 printf("%d", ans[i] - ans[i-1]);
    48             }
    49             printf("\n");
    50         }
    51         else printf("NO\n");
    52     }
    53     return 0;
    54 }

     

  • 相关阅读:
    JavaScript(第五天)【流程控制语句】
    JavaScript(第四天)【运算符】
    JavaScript(第二天)【语法,变量】
    JavaScript(第一天)【<script>标签浅析】
    JavaScript(简介)【Javascript历史】
    [LeetCode-JAVA] Substring with Concatenation of All Words
    [LeetCode-JAVA] Reverse Nodes in k-Group
    [LeetCode-JAVA] Median of Two Sorted Arrays
    [LeetCode-JAVA] Contains Duplicate IIIMaximal Square
    [LeetCode-JAVA] Contains Duplicate III
  • 原文地址:https://www.cnblogs.com/xiaobaibuhei/p/3050878.html
Copyright © 2011-2022 走看看