题目:
Download the text file here. (Right click and save link as)
This file contains all of the 100,000 integers between 1 and 100,000 (inclusive) in some random order, with no integer repeated.
Your task is to compute the number of inversions in the file given, where the
ith
row of the file indicates the
ith
entry of an array.
Because of the large size of this array, you should implement the fast divide-and-conquer algorithm covered in the video lectures. The numeric answer for the given input file should be typed in the space below.
So if your answer is 1198233847, then just type 1198233847 in the space provided without any space / commas / any other punctuation marks. You can make up to 5 attempts, and we'll use the best one for grading.
(We do not require you to submit your code, so feel free to use any programming language you want --- just type the final numeric answer in the following space.)
我的c++程序,再读入数据的时候,用while(!fin.eof())多出来一个数,跑出来结果是2407913387,没有通过测试,fuck!!!后来改为for循环读数就好了,原来是eof做的鬼,详解末尾
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
double countInversion(vector<double> & vec);
double merge(vector<double> & vec, vector<double> & v1, vector<double> & v2);
int main() {
ifstream fin("in.txt");
vector<double> init;
double temp;
//为什么用这个while循环,vector里最后一个数字会出现两遍
//while(!fin.eof()) {
// fin>>temp;
// init.push_back(temp);
//}
for(int p = 0; p < 100000; p++) {
fin>>temp;
init.push_back(temp);
}
double dataSize = init.size();
cout<<dataSize<<endl;
double x = countInversion(init);
char str[20];
sprintf(str,"%.8lf",x);
printf("%s",str);
return 0;
}
double countInversion(vector<double> & vec) {
double n = vec.size();
if( (n - 1) < 0.0000001 ) return 0;
double result = 0;
double mid = n / 2;
vector<double> v1, v2;
double k = 0;
while( k < n) {
if(k < mid) {
v1.push_back(vec[k]);
k += 1;
} else {
v2.push_back(vec[k]);
k += 1;
}
}
double c1 = countInversion(v1);
double c2 = countInversion(v2);
vec.clear();
double c3 = merge(vec, v1, v2);
result = c1 + c2 + c3;
return result;
}
double merge(vector<double> & vec, vector<double> & v1, vector<double> & v2) {
double ans = 0;
long n1 = v1.size();
long n2 = v2.size();
long p1 = 0;
long p2 = 0;
double size = n1 + n2;
for(double k = 0; k < size && p1 < n1 && p2 < n2; k++) {
if(v1[p1] <= v2[p2]) {
vec.push_back(v1[p1]);
p1 += 1;
} else {
vec.push_back(v2[p2]);
p2 += 1;
ans += n1 - p1;
}
}
while(p1 < n1) {
vec.push_back(v1[p1]);
p1 += 1; }
while(p2 < n2) {
vec.push_back(v2[p2]);
p2 += 1;
}
return ans;
}
主要是把eof()改为peek() == EOF来判别,其中peek()是取文件当前指针,EOF是文件尾尾标符,它的值为-1,所以采用这种方法就解决上面eof()的问题了,
然后我发现这样改——
(1)如果文档在最后一个数91901这一行就结束,那么输出正确答案
(2)如果在91901后面还有换行符'/n’, 即最后一个数据下面还有一个空行,那么vector里还是有100001个元素……囧
C++之EOF() http://blog.csdn.net/ixidof/article/details/4782486
http://developer.51cto.com/art/201002/183327.htm
Stream operations
#include <fstream>
ifstream in;
ofstream out;
Read/write single characters
ch = in.get();
out.put(ch);
Read/write entire lines
getline(in, line);
out << line << endl;
Formatted read/write
in >> num >> str;
out << num << str;
Use fail to check for error
if (in.fail()) ...