zoukankan      html  css  js  c++  java
  • codeforces 768c Jon Snow And His Favourite Number

    题意:

    给出一个数列,和一种操作,以及两个数x和k。

    这个操作有两个步骤:

    首先把这个数列按照升序排序,然后把所有奇数位上的数字与x异或。

    问执行k次操作之后,这个数列的最大值和最小值是多少。

    思路:

    由于每个数字异或两次之后会变回本身,所以猜测这个数列有可能会循环,所以就可以暴力计算周期,对于每一次出现的数列,看看是否与前面某次出现过的数列相同,这是暴力的思路。玄学复杂度。

    更优雅的思路:

    发现a[i]的最大值为1000,任意1000以内的两个数字异或不会超过1023,所以可以统计0到1023当中每个数字出现的次数,然后利用前缀和的思想,计算这个数字在下一次操作中对其他数字出现次数的贡献。

    假设这个数字之前有n个数字出现,这个数字的出现次数为y,当前数字为cur,操作后的数列为nex:

    1.当n为偶数,y为奇数:

    nex[cur^x] += (y/2)+1;nex[cur] += y/2;

    2.当n为偶数,y为偶数:

    nex[cur^x] += (y/2);nex[cur] += y/2;

    3.当n为奇数,y为奇数:

    nex[cur^x] += (y/2);nex[cur] += y/2+1;

    4.当n为奇数,y为偶数:

    nex[cur^x] += (y/2);nex[cur] += y/2;

    这个思路的复杂度为O(k*1024)。

    思路1代码:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 #include <iostream>
     5 #include <string>
     6 #include <map>
     7 using namespace std;
     8 
     9 const int N = 1e5 + 10;
    10 int a[N],b[105][N];
    11 
    12 int judge(int cu,int n)
    13 {
    14     for (int i = 0;i < cu;i++)
    15     {
    16         bool f = 0;
    17         for (int j = 0;j < n;j++)
    18         {
    19             if (b[i][j] != b[cu][j])
    20             {
    21                 f = 1;
    22                 break;
    23             }
    24         }
    25         
    26         if (!f) return i;
    27     }
    28     
    29     return -1;
    30 }
    31 
    32 int main()
    33 {
    34     int n,k,x;
    35     
    36     scanf("%d%d%d",&n,&k,&x);
    37     
    38     for (int i = 0;i < n;i++) scanf("%d",&a[i]);
    39     for (int i = 0;i < n;i++) b[0][i] = a[i];
    40     
    41     int cnt = 1;
    42     int pre = cnt-1;
    43     
    44     for (;cnt <= k;cnt++)
    45     {
    46         for (int i = 0;i < n;i++)
    47         {
    48             b[cnt][i] = b[cnt-1][i];
    49         }
    50         
    51         sort(b[cnt],b[cnt]+n);
    52         
    53         for (int i = 0;i <= n;i+=2)
    54         {
    55             b[cnt][i] ^= x;
    56         }
    57         
    58         pre = judge(cnt,n);
    59         
    60         if (pre != -1) break;
    61     }
    62     
    63     if (cnt >= k)
    64     {
    65         sort(b[k],b[k]+n);
    66         
    67         printf("%d %d
    ",b[k][n-1],b[k][0]);
    68     }
    69     else
    70     {
    71         int ti = cnt - pre;
    72         
    73         k = (k - pre) % ti; 
    74         
    75         k += pre;
    76         
    77         sort(b[k],b[k]+n);
    78         
    79         printf("%d %d
    ",b[k][n-1],b[k][0]);
    80     }
    81     
    82     return 0;
    83 }

    思路2代码:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 #include <iostream>
     5 #include <string>
     6 using namespace std;
     7 const int N = 2000;
     8 
     9 int a[N];
    10 int pre[N];
    11 int nex[N];
    12 
    13 int main()
    14 {
    15     int n,k,x;
    16     
    17     scanf("%d%d%d",&n,&k,&x);
    18     
    19     for (int i = 0;i < n;i++)
    20     {
    21         int y;
    22         scanf("%d",&y);
    23         a[y]++;
    24     } 
    25     
    26     for (int i = 0;i < k;i++)
    27     {
    28         memset(nex,0,sizeof(nex));
    29         pre[0] = 0;
    30         
    31         for (int j = 1;j < 1500;j++)
    32         {
    33             pre[j] = pre[j-1] + a[j-1];
    34         }
    35         
    36         for (int j = 0;j < 1500;j++)
    37         {
    38             if (a[j])
    39             {
    40                 if (pre[j] % 2)
    41                 {
    42                     if (a[j] % 2)
    43                     {
    44                         nex[j^x] += a[j] / 2;
    45                         nex[j] += a[j] / 2 + 1;
    46                     }
    47                     else
    48                     {
    49                         nex[j^x] += a[j] / 2;
    50                         nex[j] += a[j] / 2;
    51                     }
    52                 }
    53                 else
    54                 {
    55                     if (a[j] % 2)
    56                     {
    57                         nex[j^x] += (a[j]/2) + 1;
    58                         nex[j] += a[j]/2;
    59                     }
    60                     else
    61                     {
    62                         nex[j^x] += a[j]/2;
    63                         nex[j] += a[j]/2;
    64                     }
    65                 }
    66             }
    67         }
    68         
    69         for (int j = 0;j < 1500;j++)
    70         {
    71             a[j] = nex[j];
    72         }
    73     }
    74     
    75     int mx,mn;
    76     
    77     for (int i = 0;i < 1500;i++)
    78     {
    79         if (a[i])
    80         {
    81             mn = i;
    82             break;
    83         }
    84     }
    85     
    86     for (int i = 1500;i >= 0;i--)
    87     {
    88         if (a[i])
    89         {
    90             mx = i;
    91             break;
    92         }
    93     }
    94     
    95     printf("%d %d
    ",mx,mn);
    96     
    97     return 0;
    98 }
  • 相关阅读:
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    SpringCloud Alibaba微服务实战一
    Bar:柱状图/条形图
    Pie:饼图
    Gauge:仪表盘
    Funnel:漏斗图
    VSCode+latex引用bibtex参考文献
    因为报表做得太好,我被阎王爷叫走了.....
    ubuntu安装pyCUDA
  • 原文地址:https://www.cnblogs.com/kickit/p/8808817.html
Copyright © 2011-2022 走看看