【发布时间】:2016-12-17 13:16:29
【问题描述】:
我有一个问题:
给你一个序列,以字符串的形式,只有字符“0”、“1”和“?”。假设有 k'?'s。那么有 2^k 种方法将每个 '?' 替换为 '0' 或 '1',得到 2^k 个不同的 0-1 序列(0-1 序列是只有 0 和 1 的序列)。
对于每个 0-1 序列,将其反转次数定义为按非递减顺序对序列进行排序所需的最小相邻交换次数。在这个问题中,当所有 0 都出现在所有 1 之前,该序列以非递减顺序精确排序。例如,序列 11010 有 5 个反转。我们可以按照以下移动排序:11010 →→ 11001 →→ 10101 →→ 01101 →→ 01011 →→ 00111。
求 2^k 序列的求逆次数之和,取模 1000000007 (10^9+7)。
例如:
输入:??01 -> 输出:5
输入:?0? -> 输出:3
这是我的代码:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <math.h>
using namespace std;
void ProcessSequences(char *input)
{
int c = 0;
/* Count the number of '?' in input sequence
* 1??0 -> 2
*/
for(int i=0;i<strlen(input);i++)
{
if(*(input+i) == '?')
{
c++;
}
}
/* Get all possible combination of '?'
* 1??0
* -> ??
* -> 00, 01, 10, 11
*/
int seqLength = pow(2,c);
// Initialize 2D array of integer
int **sequencelist, **allSequences;
sequencelist = new int*[seqLength];
allSequences = new int*[seqLength];
for(int i=0; i<seqLength; i++){
sequencelist[i] = new int[c];
allSequences[i] = new int[500000];
}
//end initialize
for(int count = 0; count < seqLength; count++)
{
int n = 0;
for(int offset = c-1; offset >= 0; offset--)
{
sequencelist[count][n] = ((count & (1 << offset)) >> offset);
// cout << sequencelist[count][n];
n++;
}
// cout << std::endl;
}
/* Change '?' in former sequence into all possible bits
* 1??0
* ?? -> 00, 01, 10, 11
* -> 1000, 1010, 1100, 1110
*/
for(int d = 0; d<seqLength; d++)
{
int seqCount = 0;
for(int e = 0; e<strlen(input); e++)
{
if(*(input+e) == '1')
{
allSequences[d][e] = 1;
}
else if(*(input+e) == '0')
{
allSequences[d][e] = 0;
}
else
{
allSequences[d][e] = sequencelist[d][seqCount];
seqCount++;
}
}
}
/*
* Sort each sequences to increasing mode
*
*/
// cout<<endl;
int totalNum[seqLength];
for(int i=0; i<seqLength; i++){
int num = 0;
for(int j=0; j<strlen(input); j++){
if(j==strlen(input)-1){
break;
}
if(allSequences[i][j] > allSequences[i][j+1]){
int temp = allSequences[i][j];
allSequences[i][j] = allSequences[i][j+1];
allSequences[i][j+1] = temp;
num++;
j = -1;
}//endif
}//endfor
totalNum[i] = num;
}//endfor
/*
* Sum of all Num of Inversions
*/
int sum = 0;
for(int i=0;i<seqLength;i++){
sum = sum + totalNum[i];
}
// cout<<"Output: "<<endl;
int out = sum%1000000007;
cout<< out <<endl;
} //end of ProcessSequences method
int main()
{
// Get Input
char seq[500000];
// cout << "Input: "<<endl;
cin >> seq;
char *p = &seq[0];
ProcessSequences(p);
return 0;
}
结果对于小尺寸输入是正确的,但对于更大尺寸的输入,我得到时间 CPU 时间限制 > 1 秒。我也超出了内存大小。如何使其更快和最佳内存使用?我应该使用什么算法,我应该使用什么更好的数据结构?,谢谢。
【问题讨论】:
-
你没有在问题中显示你的代码(所以你的问题很不清楚)。如果你确实展示了你的代码,你的问题将变成一个 fix-my-code 问题,所以这里是题外话。
-
@BasileStarynkevitch 已更新,抱歉,我忘记发布我的代码了。
-
@BasileStarynkevitch 哦,所以有一个修复我的代码问题,抱歉不知道。
-
这一行“c++;”有理由将其标记为 c++ 代码;)
标签: c++ algorithm performance optimization data-structures