我必须解决问题,我需要你的帮助,所以提前谢谢。如你所见,标题几乎说明了一切。有一个文件“domes.in”(这是一个文本文件),它包含10.000.000对整数From(1 - 100.000),因此在第一部分中,我必须在不到1秒的时间内保存所有这些数字
首先,我尝试创建一个20.000.000个地方的int数组,这样我就可以逐个保存数字。数组的大小太大,程序没有响应。
在你阅读代码之前,先阅读任务,但请回答我的问题,不要发布任何代码,因为这是一个在线竞赛的问题,我想自己写。
#include <fstream>
using namespace std;
int main()
{
int n, m, a, b; //N(Value) M(Pairs)
int t = 0;
int r = 0;
int j;
ifstream infile("domes.in");
infile >> n >> m; //N = 100.000 M = 10.000.000
int domes[m*2];
for (j=0; j<m; j++) //For 1 to 10.000.000
{
infile >> a >> b; //Save 10.000.000 Integers
domes[t++] = a;
domes[t++] = b;
}
for (j=1; j<=n; j++) //For J = 1 - 100.000
{
int i=0;
for (int k=0; k<t; k++) //If the point J is appeared
if (domes[k] == j) //+1 Link
i++;
if (i == 1) //If Links < 2 (of number J)
r++; //+1 Point is connected with less than 2 points
} //Else move on to ++J
infile.close();
ofstream outfile("domes.out");
outfile << r;
return 0;
}
现在它似乎可以工作,但程序再次没有响应(在运行时,引发错误,表示程序停止运行。代码中还有任何其他构建错误或错误)。
我做错了什么?
TextFile: 100000 10000000
2344 3444
3345 4564
5566 9455 //随机整数高达100.000
// ..........
//编辑:我从代码中删除了结构“DOMES”,因为它是同样的东西
任务:我会用自己的话解释它,因为它很复杂。在地图上是100.000点。这些点是连接的(有10.000.000个链接)。我必须找到只有一个连接的点(每个Point至少有一个连接)。
例如:
5 4(N = 5,M = 4)N(最大值)M(对)
1 2
2 3
4 5
3 4
有2个点具有单个连接:1和5(1与2连接)和(5与4连接)。其余的点至少连接两次:
2:1-2,2-3
3:2-3,3-4
4:4-3,4-5
答案 0 :(得分:1)
第一个问题是算法的成本所在,这很可能与读取输入无关。如果我理解你的算法,你正在读取所有数字(节点id)到内存,然后你迭代链接,你选择一个节点,并尝试找到是否有更多链接包含该节点。该算法是O(N ^ 2),对于大量的算法来说,它会变成大量的操作。
如果你需要知道的是有多少节点有一个连接,你需要在内存中维护的每个节点一个条目(100k)。每个节点需要保留多少信息?很少,例如,仅检测哪些节点具有单个连接,您可以存储节点被看到的次数(0 - >从未见过)。一次读一行,增加两个节点的计数(成本:O(N),N是链接数)。在该过程结束时,扫描条目并打印出计数为1的条目(成本:O(M),其中M是节点数)。算法的总成本在节点数+边数之和是线性的,在节点数上有线性空间要求。
将其与原始方法进行比较:空间400k对160M;操作10M对10 ^ 14。
在大多数编程竞赛中,目标不是削减运营成本,而是提高解决方案的渐近复杂度。似乎适用于小输入的天真解决方案不适用于大型输入。对于10号问题,O(N ^ 2)基本上是100次运算......几乎是一个常数因子!但随着问题的增加,尺寸100变为10k,尺寸1000则为1M ......
答案 1 :(得分:1)
对于大数据的I / O,C ++流比它们的C亲属慢。我相信你可以加快fopen()
和fwrite()
<cstdio>
的写作速度。通过这样做,您可以一次性编写整个数组,并且可能不会出现崩溃问题。
答案 2 :(得分:0)
不确定这是否对在线比赛有用。但是,为了快速访问文件,我会尝试内存映射文件。 (如果您的平台支持POSIX,请使用mmap(),或者在Windows上支持CreateFileMapping和MapViewOfFile)基本上,您可以像写入内存一样写入文件。