zoukankan      html  css  js  c++  java
  • 18.11.28 内排序四则

    求逆序对数(10分)

    题目内容:

    对于一个长度为N的整数序列A,满足i < j 且 Ai > Aj.的数对(i,j)称为整数序列A的一个逆序
    <j<=n且ai><j<=n且ai><j<=n且ai><j<=n且ai>

    请求出整数序列A的所有逆序对个数

     

    输入格式:

    输入包含多组测试数据,每组测试数据有两行
    第一行为整数N(1 <= N <= 20000),当输入0时结束
    第二行为N个整数,表示长为N的整数序列

     

    输出格式:

    每组数据对应一行,输出逆序对的个数

     

    输入样例:

    5
    1 2 3 4 5
    5
    5 4 3 2 1
    1
    1
    0

     

    输出样例:

    0
    10
    0

     

    时间限制:200ms内存限制:32000kb
     1 #include <iostream>
     2 #include <string.h>
     3 #include <algorithm>
     4 #include <stack>
     5 #include <string>
     6 #include <math.h>
     7 #include <queue>
     8 #include <stdio.h>
     9 #include <string.h>
    10 #include <vector>
    11 #include <fstream>
    12 #include <set>
    13 #define maxn 20005
    14 #define inf 999999
    15 
    16 using namespace std;
    17 int n, a[maxn],tmp[maxn];
    18 int sum;
    19 
    20 inline void swap(int x, int y) {
    21     int tmp = a[x];
    22     a[x] = a[y];
    23     a[y] = tmp;
    24 }
    25 
    26 void mysort(int left,int right){
    27     if (left >= right)return;
    28     int mid = (left + right) / 2;
    29     mysort(left, mid);
    30     mysort(mid + 1, right);
    31     int p1 = left, p2 = mid+1,i=left;
    32     while (p1<=mid&&p2<=right) {
    33         if (a[p1] <= a[p2])
    34             tmp[i++] = a[p1++];
    35         else if (a[p2] < a[p1])
    36         {
    37             tmp[i++] = a[p2++];
    38             sum += mid - p1 + 1;
    39         }
    40     }
    41     while (p2 <= right)
    42         tmp[i++] = a[p2++];
    43     while (p1 <= mid)
    44         tmp[i++] = a[p1++];
    45     for (int i = left; i <= right; i++)a[i] = tmp[i];
    46 }
    47 
    48 void init() {
    49     while (scanf("%d", &n) != EOF&&n) {
    50         sum = 0;
    51         for (int i = 1; i <= n; i++)
    52             scanf("%d", &a[i]);
    53         mysort(1,n);
    54         printf("%d
    ", sum);
    55     }
    56 }
    57 
    58 int main()
    59 {
    60     init();
    61     return 0;
    62 }
    View Code

    超级快排(10分)

    题目内容:

    在这个问题中,你需要分析特别的算法。这个算法通过对一个包含n个元素的进行操作,一直交换相邻的两个序列的元素直到整个序列呈升序排列。对于输入序列9 1 0 5 4 ,Ultra-QuickSort最终得到的输出为0 1 4 5 9 .你的任务就是来计算出Ultra-QuickSort 至少需要多少swap操作来最终达到对一个给定的输入序列排好序的目标。

     

    输入格式:

    输入包括多组测试数据。每组测试数据以一行包括一个单独的整数n开始(n<500,000,是输入序列的长度)。每组测试数据接下来的n行包括一个单独的整数a[i],a[i]≤ 999,999,999,代表输入序列第n个元素。输入以一个长度n为0的序列终止。这个序列不应该被处理。

     

    输出格式:

    对于每组测试数据,你的程序应该输入单独的一行,包括一个整数op,代表对该输入序列进行排序所需要最小的交换次数。

     

    输入样例:

     

    5
    9
    1
    0
    5
    4
    3
    1
    2
    3
    0

    输出样例:

    6
    0

     

    时间限制:200ms内存限制:32000kb
     1 #include <iostream>
     2 #include <string.h>
     3 #include <algorithm>
     4 #include <stack>
     5 #include <string>
     6 #include <math.h>
     7 #include <queue>
     8 #include <stdio.h>
     9 #include <string.h>
    10 #include <vector>
    11 #include <fstream>
    12 #include <set>
    13 #define maxn 20005
    14 #define inf 999999
    15 
    16 using namespace std;
    17 int n, a[maxn],tmp[maxn];
    18 int sum;
    19 
    20 inline void swap(int x, int y) {
    21     int tmp = a[x];
    22     a[x] = a[y];
    23     a[y] = tmp;
    24 }
    25 
    26 void mysort(int left,int right){
    27     if (left >= right)return;
    28     int mid = (left + right) / 2;
    29     mysort(left, mid);
    30     mysort(mid + 1, right);
    31     int p1 = left, p2 = mid+1,i=left;
    32     while (p1<=mid&&p2<=right) {
    33         if (a[p1] <= a[p2])
    34             tmp[i++] = a[p1++];
    35         else if (a[p2] < a[p1])
    36         {
    37             tmp[i++] = a[p2++];
    38             sum += mid - p1 + 1;
    39         }
    40     }
    41     while (p2 <= right)
    42         tmp[i++] = a[p2++];
    43     while (p1 <= mid)
    44         tmp[i++] = a[p1++];
    45     for (int i = left; i <= right; i++)a[i] = tmp[i];
    46 }
    47 
    48 void init() {
    49     while (scanf("%d", &n) != EOF&&n) {
    50         sum = 0;
    51         for (int i = 1; i <= n; i++)
    52             scanf("%d", &a[i]);
    53         mysort(1,n);
    54         printf("%d
    ", sum);
    55     }
    56 }
    57 
    58 int main()
    59 {
    60     init();
    61     return 0;
    62 }
    View Code

    Sequence(10分)

    题目内容:

    给定m个数字序列,每个序列包含n个非负整数。我们从每一个序列中选取一个数字组成一个新的序列,显然一共可以构造出n^m个新序列。接下来我们对每一个新的序列中的数字进行求和,一共会得到n^m个和,请找出最小的n个和

     

    输入格式:

    输入的第一行是一个整数T,表示测试用例的数量,接下来是T个测试用例的输入
    每个测试用例输入的第一行是两个正整数m(0 < m <= 100)和n(0 < n <= 2000),然后有m行,每行有n个数,数字之间用空格分开,表示这m个序列
    序列中的数字不会大于10000

     

    输出格式:

    对每组测试用例,输出一行用空格隔开的数,表示最小的n个和

     

    输入样例:

    1
    2 3
    1 2 3
    2 2 3

     

    输出样例:

    3 3 4

     

    时间限制:100ms内存限制:32000kb
      1 #include <iostream>
      2 #include <string.h>
      3 #include <algorithm>
      4 #include <stack>
      5 #include <string>
      6 #include <math.h>
      7 #include <queue>
      8 #include <stdio.h>
      9 #include <string.h>
     10 #include <vector>
     11 #include <fstream>
     12 #include <set>
     13 #define maxn 2005
     14 #define inf 999999
     15 
     16 using namespace std;
     17 int n, m;
     18 struct maxheap {
     19     int num[maxn];
     20     int cursize;
     21     maxheap() {
     22         memset(num, 0, sizeof(num));
     23         cursize = 0;
     24     }
     25     void siftdown(int p) {
     26         int i = p;
     27         int j = 2 * p;
     28         int val = num[p];
     29         while (j <= cursize) {
     30             if (j <= cursize - 1 && num[j + 1] > num[j])
     31                 j++;
     32             if (num[j] > val)
     33             {
     34                 num[i] = num[j];
     35                 i = j; j = 2 * j;
     36             }
     37             else break;
     38         }
     39         num[i] = val;
     40     }
     41     void siftup(int p) {
     42         int i = p;
     43         int val = num[i];
     44         while (i > 1 && num[i / 2] < val) {
     45             num[i] = num[i / 2];
     46             i = i/2;
     47         }
     48         num[i] = val;
     49     }
     50     void makeheap(int*a) {
     51         cursize = n;
     52         for (int i = 1; i <= n; i++)
     53             num[i] = a[i];
     54         for (int i = n / 2; i >= 0; i--)
     55             siftdown(i);
     56     }
     57     void add(int x) {
     58         if (cursize == n)
     59         {
     60             num[1] = x;
     61             siftdown(1);
     62         }
     63         else
     64         {
     65             num[++cursize] = x;
     66             siftup(cursize);
     67         }
     68     }
     69     void removemax() {
     70         num[1] = num[cursize--];
     71         siftdown(1);
     72     }
     73 }all[2];
     74 
     75 void init() {
     76     int kase;
     77     scanf("%d", &kase);
     78     while (kase--) {
     79         scanf("%d%d", &m, &n);
     80         maxheap sum;
     81         int a[maxn], b[maxn];
     82         for (int i = 1; i <= n; i++) 
     83             scanf("%d", &a[i]);
     84         sort(a + 1, a + n + 1);
     85         for (int i = 2; i <= m; i++) {
     86             for (int j = 1; j <= n; j++)
     87                 scanf("%d", &b[j]);
     88             for (int j = 1; j <= n; j++)
     89                 sum.add(a[j] + b[1]);
     90             for (int j = 2; j <= n; j++)
     91                 for (int k = 1; k <= n; k++)
     92                     if (a[k] + b[j] < sum.num[1])
     93                         sum.add(a[k] + b[j]);
     94             for (int j = 1; j <= n; j++) {
     95                 {
     96                     a[n-j+1] = sum.num[1];
     97                     sum.removemax();
     98                 }
     99             }
    100         }
    101         printf("%d", a[1]);
    102         for (int i = 2; i <=n; i++)
    103             printf(" %d", a[i]);
    104         printf("
    ");
    105     }
    106 }
    107 
    108 int main()
    109 {
    110     init();
    111     return 0;
    112 }
    View Code

    这道题……堆也是写得很糟心啊

    促销活动(10分)

    题目内容:

    Great Bytelandish超市联盟想请你编写一个程序模拟计算促销活动的开销

    促销活动遵守以下规则:

    参加促销活动的客户,可以在消费结束后将自己的消费账单投入一个指定的投票箱里

    当一天的促销活动结束时,将从投票箱中选出两份账单:一份是消费金额最大的账单,一份是消费金额最小的账单。最大金额账单对应的客户,将得到一笔奖金,奖金数等于金额最大的账单与金额最小的账单之间的差值。输入保证总可以找到这样的两份账单

    为了避免一个消费者重复获奖,抽出的两份账单都不能放回投票箱,但是其他账单还会留在投票箱里继续参加下一天的促销活动

    你的任务是根据每天促销活动的信息,计算出超市在整个促销活动期间的奖金开销

     

    输入格式:

    输入的第一行是一个整数n(1 <= n <= 5000),表示促销活动的天数
    接下来有n行输入,每行有若干个非负整数,整数之间用空格分隔
    第i+1行的数据代表第i天的账单信息,每行的第一个整数k(0 <= k <= 10^5)表示当天有多少个账单,接下来是k个正整数,对应每份账单的金额,账单金额都不超过10^6
    整个促销活动涉及到的账单数之和不超过10^6

     

    输出格式:

    一个整数,表示超市在整个促销活动中的奖金开销

     

    输入样例:

     

    5
    3 1 2 3
    2 1 1
    4 10 5 5 1
    0
    1 2

    输出样例:

    19
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <iostream>
     5 #include <algorithm>
     6 #include<set>
     7 using namespace std;
     8 
     9 int n;
    10 multiset<int>q;
    11 
    12 int main()
    13 {
    14     scanf("%d", &n);
    15     int sum = 0;
    16     for (int i = 1; i <= n; i++)
    17     {
    18         int x;
    19         scanf("%d", &x);
    20         for (int j = 1; j <= x; j++)
    21         {
    22             int a;
    23             scanf("%d", &a);
    24             q.insert(a);
    25         }
    26         multiset<int>::iterator i1=q.begin(), i2=q.end();
    27         i2--;
    28         int min = *i1, max = *i2;
    29         sum += max - min;
    30         q.erase(i1);
    31         q.erase(i2);
    32     }
    33     printf("%d
    ", sum);
    34     return 0;
    35 }
    View Code

    这道题我到现在都还没改对,所以上面的是STL水过的代码

    我本来是想懒惰地复制最小堆改改变成最大堆,没想到死活有个点过不去(又改了一次升级到了2个点……手动微笑)

    代码存下放这里

      1 #include <iostream>
      2 #include <string.h>
      3 #include <algorithm>
      4 #include <stack>
      5 #include <string>
      6 #include <math.h>
      7 #include <queue>
      8 #include <stdio.h>
      9 #include <string.h>
     10 #include <vector>
     11 #include <fstream>
     12 #include <set>
     13 #define maxn 5001
     14 #define inf 999999
     15 
     16 using namespace std;
     17 int day;
     18 struct maxheap {
     19     int num[maxn];
     20     int cursize;
     21     int minp;
     22     int minval;
     23     maxheap() {
     24         memset(num, 0, sizeof(num));
     25         cursize = 0;
     26         minval = inf;
     27     }
     28     int siftdown(int p) {
     29         int i = p;
     30         int j = 2 * p;
     31         int val = num[p];
     32         while (j <= cursize) {
     33             if (j <= cursize - 1 && num[j + 1] > num[j])
     34                 j++;
     35             if (num[j] > val)
     36             {
     37                 num[i] = num[j];
     38                 i = j; j = 2 * j;
     39             }
     40             else break;
     41         }
     42         num[i] = val;
     43         return i;
     44     }
     45     int siftup(int p) {
     46         int i = p;
     47         int val = num[i];
     48         while (i > 1 && num[i / 2] < val) {
     49             if (i / 2 == minp)
     50                 minp = i;
     51             num[i] = num[i / 2];
     52             i = i/2;
     53         }
     54         num[i] = val;
     55         return i;
     56     }
     57     void add(int x) {
     58         if (cursize == day)
     59         {
     60             num[minp] = x;
     61             int i=siftup(minp);
     62             minval = x, minp = i;
     63             for(int i=cursize/2;i<=cursize;i++)
     64                 if (num[i] < minval) {
     65                     minp = i;
     66                     minval = num[i];
     67                 }
     68         }
     69         else
     70         {
     71             num[++cursize] = x;
     72             int i=siftup(cursize);
     73             if (x < minval) {
     74                 minval = x;
     75                 minp = i;
     76             }
     77         }
     78     }
     79     void removemax() {
     80         if (cursize == 1) {
     81             minval = inf;
     82             cursize = 0;
     83         }
     84         else {
     85             num[1] = num[cursize--];
     86             int i = siftdown(1);
     87             if (minp == cursize + 1)
     88                 minp = i;
     89         }
     90     }
     91     void removep(int x) {
     92         if (minval == x)
     93         {
     94             num[minp] = num[cursize--];
     95             minval = num[minp];
     96             for (int i = cursize / 2; i <= cursize; i++)
     97                 if (num[i] < minval) {
     98                     minp = i;
     99                     minval = num[i];
    100                 }
    101             if (cursize == 0)
    102                 minval = inf;
    103         }
    104     }
    105 };
    106 struct minheap {
    107     int num[maxn];
    108     int cursize;
    109     int maxp;
    110     int maxval;
    111     minheap() {
    112         memset(num, 0, sizeof(num));
    113         cursize = 0;
    114         maxval = 0;
    115     }
    116     int siftdown(int p) {
    117         int i = p;
    118         int j = 2 * p;
    119         int val = num[p];
    120         while (j <= cursize) {
    121             if (j <= cursize - 1 && num[j + 1] < num[j])
    122                 j++;
    123             if (num[j] < val)
    124             {
    125                 num[i] = num[j];
    126                 i = j; j = 2 * j;
    127             }
    128             else break;
    129         }
    130         num[i] = val;
    131         return i;
    132     }
    133     int siftup(int p) {
    134         int i = p;
    135         int val = num[i];
    136         while (i > 1 && num[i / 2] > val) {
    137             if (i / 2 == maxp)
    138                 maxp = i;
    139             num[i] = num[i / 2];
    140             i = i / 2;
    141         }
    142         num[i] = val;
    143         return i;
    144     }
    145     void add(int x) {
    146         if (cursize == day)
    147         {
    148             num[maxp] = x;
    149             int i=siftup(maxp);
    150             maxval = x, maxp = i;
    151             for(int i=cursize/2;i<=cursize;i++)
    152                 if (num[i] > maxval)
    153                 {
    154                     maxp = i;
    155                     maxval = num[i];
    156                 }
    157         }
    158         else
    159         {
    160             num[++cursize] = x;
    161             int i=siftup(cursize);
    162             if (x > maxval) {
    163                 maxval = x;
    164                 maxp = i;
    165             }
    166         }
    167     }
    168     void removemax() {
    169         if (cursize == 1) {
    170             cursize = 0;
    171             maxval = 0;
    172         }
    173         else {
    174             num[1] = num[cursize--];
    175             int i = siftdown(1);
    176             if (maxp == cursize + 1)
    177                 maxp = i;
    178         }
    179     }
    180     void removep(int x) {
    181         if (maxval == x)
    182         {
    183             num[maxp] = num[cursize--];
    184             maxval = num[maxp];
    185             for (int i = cursize / 2; i <= cursize; i++)
    186                 if (num[i] < maxval) {
    187                     maxp = i;
    188                     maxval = num[i];
    189                 }
    190         }
    191     }
    192 };
    193 
    194 void init() {
    195     scanf("%d", &day);
    196     minheap getmin;
    197     maxheap getmax;
    198     int sum = 0;
    199     int c = 0;
    200     for (int i = 1; i <= day; i++) {
    201         int n;
    202         scanf("%d", &n);
    203         c += n;
    204         for (int j = 1; j <= n; j++)
    205         {
    206             int x;
    207             scanf("%d", &x);
    208             if(x<getmin.maxval||getmin.cursize!=day)
    209                 getmin.add(x);
    210             if(x>getmax.minval || getmax.cursize != day)
    211                 getmax.add(x);
    212         }
    213         int max = getmax.num[1], min = getmin.num[1];
    214         sum += max - min;
    215         getmax.removemax();
    216         getmin.removemax();
    217         if (c <= day)
    218         {
    219             getmax.removep(min);
    220             getmin.removep(max);
    221         }
    222         c -= 2;
    223     }
    224     printf("%d
    ", sum);
    225 }
    226 
    227 int main()
    228 {
    229     init();
    230     return 0;
    231 }
    View Code
    注定失败的战争,也要拼尽全力去打赢它; 就算输,也要输得足够漂亮。
  • 相关阅读:
    C#反射(一)
    找回密码
    常用的webservice接口 .
    C# 反射应用技术
    Delphi简介
    C#程序思想简介
    如何跨线程访问window控件
    C#如何判断某个文件夹是否为共享,访问权限为只读
    Delphi基础
    Web Service接口
  • 原文地址:https://www.cnblogs.com/yalphait/p/10032225.html
Copyright © 2011-2022 走看看