• codeforces B. Jeff and Periods 解题报告


    题目链接:http://codeforces.com/problemset/problem/352/B

    题目意思:给出一个长度为n的序列   a1, a2, ..., an(序号i,1 <= i <= n)。需要从这个序列中,找出符合这两个条件的数:1、这个数在序列 a1, a2, ..., an 中; 2、该数的所有位置(也就是序号i)构成等差数列。一旦有一个位置不满足(此时和上一个位置所求出的公差就与之前的公差不相等),这个数就不符合条件,不应该输出。找完之后,输出所有满足这两个条件的数的总数,还有这些数以及对应的公差。

         值得注意的地方有:当这个数在序列中只出现一次的时候,也属于可输出的,此时它的公差为0,也就是ST 1的情况; 还有,整个序列一个都找不到这样的数,要输出0。

         这条是我赛中第一次提交的,因为一下子就看懂题目了。不过赛中是没过到啦,以为很简单...赛后,修改,调试,整整两天多,终于AC了。方法比较笨,还是那句话,自己写的特别有感觉。后来看了别人用vector来做,代码长度缩短了很多。看来还是需要学一下容器啊~~~

    方法一:

        

    TimeMemory
    92 ms 2000 KB
      1 #include <iostream>
      2 #include <algorithm>
      3 #include <cstdio>
      4 #include <cstdlib>
      5 #include <cstring>
      6 using namespace std;
      7 
      8 const int maxn = 1e5 + 5;
      9 
     10 struct pairs
     11 {
     12     int index;    // 保存位置的编号i
     13     int num;      // 保存序列的数,即题目中的a[i]
     14 }p[maxn];
     15 
     16 int cmp(pairs a, pairs b)
     17 {
     18     if (a.num != b.num)
     19         return a.num < b.num;
     20     return a.index < b.index;   // 关键!!!保证公差是正数,否则过不了test 10
     21 }
     22 
     23 int c[maxn], b[maxn];
     24 int f[maxn];
     25 
     26 int main()
     27 {
     28     int i, j, k, n, sum;
     29     while (scanf("%d", &n) != EOF)
     30     {
     31         memset(c, 0, sizeof(c));
     32         for (j = i = 1; i <= n; i++)
     33         {
     34             scanf("%d", &p[i].num);
     35             c[p[i].num]++;    // 统计a[i]在序列中出现多少次
     36             if (c[p[i].num] == 1)
     37             {
     38                 b[j++] = p[i].num;   // 保存a[i]
     39             }
     40             p[i].index = i;
     41         }
     42         k = j;
     43         sort(p+1, p+n+1, cmp);   // 序列a的数从小到大排序,如果相同,则按具体的位置从小到大排序
     44         sort(b+1, b+j);   // 保证输出的序列是递增的
     45     /*  for (i = 1; i <= n; i++)
     46         {
     47             printf("p[%d].index = %d, p[%d].num = %d\n", i, p[i].index, i, p[i].num);
     48         }
     49     */
     50         memset(f, 0, sizeof(f));   // 保存公差
     51         int tmp, j, flag, minus;
     52         sum = 0;
     53         for (i = 1; i <= n; i += c[p[i].num])
     54         {
     55     //      printf("i = %d\n", i);
     56     //      printf("c[%d] = %d\n", p[i].num, c[p[i].num]);
     57             if (c[p[i].num] == 1)   // 在序列中只出现一次的数,公差设为0
     58             {
     59                 f[p[i].num] = 0;
     60                 sum++;        // 也属于可输出的
     61             }
     62             else
     63             {
     64                 flag = 0;
     65                 for (j = i; j < c[p[i].num]+i-1; j++)  // 检测相同数字的公差是否相等
     66                 {
     67     //              printf("j = %d\n", j);
     68                     if (j == i)      // 用第一、二个的位置算出公差即可,下面用这个公差来检查其他位置的公差是否和这个公差相等
     69                     {   
     70                         tmp = p[j+1].index - p[j].index;  
     71     //                  printf("tmp = %d\n", tmp);
     72                     }
     73                     minus = p[j+1].index - p[j].index;  
     74     //              printf("minus = %d\n\n", minus);
     75                     if (tmp != minus)
     76                     {
     77                         f[p[i].num] = -1;   // 发现有一个位置不等于之前算出的公差
     78                         flag = 1;
     79         //              printf("error !!!!\n\n");
     80                 
     81                     }
     82                 }
     83                 if (j == c[p[i].num]+i-1 && !flag)  // 相同的数的所有位置算出的公差都相等
     84                 {
     85                     sum++;
     86     //              printf("success!!!\n");
     87                     f[p[i].num] = tmp;   // 保存公差
     88                 }
     89             }           
     90         }
     91         if (sum)
     92         {
     93             printf("%d\n", sum);   // 符合条件的总数
     94             for (i = 1; i < k; i++)
     95             {
     96                 if (f[b[i]] != -1)
     97                 {
     98                     printf("%d %d\n", b[i], f[b[i]]);
     99                 }
    100             }
    101         }
    102         else
    103             printf("0\n");
    104     }
    105     return 0;
    106 }

    方法二:

    TimeMemory
    92 ms 4900 KB

    用vector方法写的,记得每次都要清空。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <vector>
     6 using namespace std;
     7 
     8 const int maxn = 1e5 + 5;
     9 const int maxm = 5;
    10 
    11 vector <int> s[maxn];
    12 int ans[maxn][maxm];
    13 
    14 int main()
    15 {
    16     int i, j, n, tmp, flag;
    17     while (scanf("%d", &n) != EOF)
    18     {
    19         memset(s, 0, sizeof(s));
    20         for (i = 1; i <= n; i++)
    21         {
    22             scanf("%d", &tmp);
    23             s[tmp].push_back(i);
    24         }
    25         int d, len, cnt = 0;
    26         for (i = 1; i <= maxn; i++)
    27         {
    28             flag = 0;
    29             len = s[i].size();
    30             if (len == 0)
    31                 continue;
    32             else if (len == 1)
    33             {
    34                 ans[cnt][0] = i;
    35                 ans[cnt][1] = 0;
    36                 cnt++;
    37             }
    38             else
    39             {
    40                 d = s[i][1] - s[i][0];
    41                 if (len ==  2)
    42                 {
    43                     ans[cnt][0] = i;
    44                     ans[cnt][1] = d;
    45                     flag = 1;
    46                     cnt++;
    47                 }
    48             //  printf("d = %d\n", d);
    49                 if (!flag)
    50                 {
    51                    for (j = 2; j < len; j++)
    52                     {
    53                         if (s[i][j] - s[i][j-1] != d)
    54                             break;
    55                     }
    56                     if (j == len)
    57                     {
    58                         ans[cnt][0] = i;
    59                         ans[cnt][1] = d;
    60                         cnt++;
    61                     }
    62                 }
    63             }
    64         }
    65         printf("%d\n", cnt);
    66         for (i = 0; i < cnt; i++)
    67         {
    68             printf("%d %d\n", ans[i][0], ans[i][1]);
    69         }
    70     }
    71     return 0;
    72 }
  • 相关阅读:
    JS防抖和节流
    移动端屏幕适配
    vue、react对比
    HTTP缓存
    程序员必备技术网站
    W3C标准、表现与数据分离、web语义化
    VUE的响应式原理
    react更新渲染及渲染原理
    ubuntu下mysql的环境搭建及使用
    apktool反编译工具
  • 原文地址:https://www.cnblogs.com/windysai/p/3354499.html
Copyright © 2020-2023  润新知