我正在尝试从澳大利亚信息学培训网站解决Slicing Paradise。这个想法是你有一系列的块(实际上是语句中的林,我的代码中是land
),并且每次都会删除一个块(或转换为一个度假区),这可能会增加或减少连续(森林)块的运行次数。我要计算历史最大次数。输入是块数N,接着是N行,给出每个块的移除时间。时间是从1开始的连续整数。
我的代码工作正常(我认为),但对于一些较大的案例来说,它太慢了。有人可以建议一个简单的快速工作解决方案,或者可以对我的任何改进使其在O(N)中运行吗?
#include <cstdio>
FILE* infile;
FILE* outfile;
int N,c,j,l,best;
int main(){
infile=fopen("slicein.txt","r");
outfile=fopen("sliceout.txt","w");
fscanf(infile,"%d\n",&N);
int land[N+1];
int location[N+1];
for (int i=1;i<=N;i++){
fscanf(infile,"%d\n",&location[i]);
land[i]=0;
}
j=1;l=1;c=1;
for (int i=1;i<=N;i++){
if (location[i]==j){
land[i]=1;
if (land[i+1]!=1 && land[i-1]!=1 && i!=N && i!=1) c++;
else if (land[i-1]==1 && land[i+1]==1 && i!=N && i!=1) c--;
j++;
if (c>best) best=c;
i=0;
}
if (i==N && l!=N*N){
i=0;
}
else if (l==N*N) break;
l++;
}
fprintf(outfile,"%d\n",best);
fclose(infile);
fclose(outfile);
return 0;
}
答案 0 :(得分:3)
你的问题是你基本上有两个嵌套循环,一个用于j
,另一个用于i
,尽管你并没有明确地写出来。这为您提供了一种O(N)方法来查找当前位置,这相当于O(N 2 )总成本。
基本信息是,在每轮j
中,您需要找到在该轮中转换的位置i
。您可以在阅读输入时为其构建地图。而不是将location
作为地图从一个位置到另一个时间,使其成为一个时间到位置的地图:
for (int i=1;i<=N;i++){
int t;
fscanf(infile,"%d\n",&t);
location[t] = i;
land[i]=0;
}
然后你可以用一个O(N)循环来做,一切都应该没问题。确保索引正确,因为您似乎在某些地方使用基于索引的索引,而在其他地方使用基于零的索引。
答案 1 :(得分:0)
无法找出您的解决方案,但以下是 O(nlogn)中执行该算法的算法: -
- 在矢量
中存储tupples(i,time [i])- 根据时间[i]
对矢量进行排序- 维护一个布尔数组以检查是否采用了绘图。
- 最初的所有 = false
- 按排序顺序开始构建绘图。
- 最初的森林= 1
- 构建绘图时,检查布尔数组中的相邻绘图。
- 如果两者都被占用那么森林=森林 - 1
- 如果一个人被占用则没有变化
- 如果两者都是空森林=森林+ 1
- 每次施工后检查森林ID是否大于最大值。
醇>
时间复杂度: -
Sorting takes O(logn)
plot construction in sorted order O(n)
答案 2 :(得分:0)
对于任何对此感兴趣的人,我的回答是:
#include <cstdio>
FILE* infile;
FILE* outfile;
int N,c,j,l,b,best;
int main(){
infile=fopen("slicein.txt","r");
outfile=fopen("sliceout.txt","w");
fscanf(infile,"%d\n",&N);
int land[N+1];
int location[N+1];
j=1;l=1;c=1;b=1;
for (int i=1;i<=N;i++){
int t;
fscanf(infile,"%d\n",&t);
location[t]=i;
land[i]=0;
}
for (int i=1;i<=N;i++){
land[location[i]]=1;
if (land[location[i]-1]!=1 && land[location[i]+1]!=1 && location[i]!=1 && location[i]!=N) c++;
else if (land[location[i]-1]==1 && land[location[i]+1]==1 && location[i]!=1 && location[i]!=N) c--;
else if (land[location[i]-1]==1 && location[i]==N) c--;
else if (land[location[i]+1]==1 && location[i]==1) c--;
if (c>best) best=c;
}
fprintf(outfile,"%d\n",best);
fclose(infile);
fclose(outfile);
return 0;}
感谢MvG建议算法:)