poj-1007

来源:互联网 发布:jquery 数组添加对象 编辑:程序博客网 时间:2024/06/05 15:32
//428K  0MS G++ mergeSort#include <cstdio>#include <cstring>#include <cstdlib>char str1[110];char str2[110];char tmp1[110];char tmp2[110];char strs[110][110];struct StrInfo{    int reverseOrderNum;    int pos;} strInfos[110];typedef struct StrInfo StrInfo;int comp(const void * a,const void * b) {    return (*(StrInfo*)a).reverseOrderNum            - (*(StrInfo*)b).reverseOrderNum;}int MergeSort(char * array, int begin, int end) {    // printf("%d %d\n", begin ,end);    if (begin == end) {        return 0;    }    int totalReverseOrderNum = 0;    int mid = (begin + end)>>1;    int leftPartReverseOrderNum = MergeSort(array, begin, mid);    int rightPartReverseOrderNum = MergeSort(array, mid + 1, end);    totalReverseOrderNum += leftPartReverseOrderNum;    totalReverseOrderNum += rightPartReverseOrderNum;    memset(tmp1, 0, sizeof(tmp1));    memset(tmp2, 0, sizeof(tmp2));    // printf("P1 %d %d\n", mid - begin + 1, end - (mid + 1) + 1);    memcpy(tmp1, array + begin, mid - begin + 1);    memcpy(tmp2, array + mid + 1, end - (mid + 1) + 1);    // printf("STR1: %s STR2: %s\n", tmp1, tmp2);    int leftIndex = 0;    int rightIndex = 0;    int index = begin;    while(tmp1[leftIndex] && tmp2[rightIndex]) {        if (tmp1[leftIndex] <= tmp2[rightIndex]) {            // printf("%c < %c\n", tmp1[leftIndex], tmp2[rightIndex]);            array[index] = tmp1[leftIndex];            leftIndex++;        } else {            array[index] = tmp2[rightIndex];                // printf("%c >= %c %d %d\n", tmp1[leftIndex], tmp2[rightIndex], leftIndex, rightIndex);            totalReverseOrderNum += mid - begin + 1 - leftIndex;            rightIndex++;        }        index++;    }    while(tmp1[leftIndex]) {        array[index++] = tmp1[leftIndex++];    }    while(tmp2[rightIndex]) {        array[index++] = tmp2[rightIndex++];    }    // memset(tmp1, 0, sizeof(tmp1));    // memcpy(tmp1, array + begin, end - begin + 1);    // printf("FINAL: %s\n", tmp1);    return totalReverseOrderNum;}int InversionNumber(char* s, int len)  {      int ans=0;  //s逆序数      int A,C,G;  //各个字母出现次数,T是最大的,无需计算T出现次数      A=C=G=0;      for(int i=len-1;i>=0;i--)      {          switch(s[i])          {              case 'A':A++;break;  //A是最小的,无逆序数              case 'C':                   {                       C++;                       ans+=A;  //当前C后面出现A的次数就是这个C的逆序数                       break;                   }              case 'G':                  {                      G++;                      ans+=A;                      ans+=C;                      break;                  }              case 'T':                  {                      ans+=A;                      ans+=C;                      ans+=G;                      break;                  }          }      }      return ans;  }  int getReverseOrderNum(char * str) {    memcpy(str2, str, strlen(str) + 1);    // printf("%s\n", str2);    int res = MergeSort(str2, 0, strlen(str2) - 1);    // printf("%s\n", str2);    // int res = InversionNumber(str2, strlen(str2));    return res; }int length;int strNum;int main() {    while(scanf("%d %d", &length, &strNum) != EOF) {        for (int i = 0; i < strNum; i++) {            scanf("%s", strs[i]);            strInfos[i].pos = i;            strInfos[i].reverseOrderNum = getReverseOrderNum(strs[i]);            // strInfos[i].reverseOrderNum = InversionNumber(strs[i], strlen(strs[i]));            // printf("%d\n", strInfos[i].reverseOrderNum);        }        qsort(strInfos, strNum, sizeof(StrInfo), comp);        for (int i = 0; i < strNum; i++) {            printf("%s\n", strs[strInfos[i].pos]);        }    }}


MLGB,strInfos数组开小了,WA了好几次

算是一道很好的基础题,因为这道题可以是归并排序和快速排序的综合题,

首先要用归并排序(也可以树状数组,线段树,不过归并最接地气)求出每个字符串的逆序数(在这里犯了好多细节错误,以后要好好理理, 并且因为本题的特殊性,只有四种字母,因此可以用o(n)方法来求,写起来简单些,虽然不算快), 然后就是快速排序(不想写了,直接qsort)将逆序数俺从小到大排,输出对应的字符串就可以。


0 0