纪中12日T1 2307. 选择
2307. 选择
(File IO): input:choose.in output:choose.out
时间限制: 1000 ms 空间限制: 262144 KB 具体限制
题目描述
输入
输出
样例输入
样例输出
数据范围限制
提示
【样例解释】
样例一:L = 1, R = 3 样例二:L = 2, R = 5
Solution
题目恶心到我能看懂
Algorithm(n3)
枚举l,枚举r,枚举i∈[l,r];累加sum,minans打擂台
Code(≌0分)
#include<iostream>//不想OI一场空,千万别用万能头 #include<algorithm>//快排sort() #include<cstdio>//能不用cin就不用 #include<cstring> #include<map> #include<cmath> #define IL inline using namespace std; IL void fin(){freopen("choose.in","r",stdin);} IL void fout(){freopen("choose.out","w",stdout);} IL void fio() { fin(); fout(); } int n,a[300002],b[300002],ans,minans=0x3f3f3f3f; int main() { // fio(); cin>>n; for(int i=0;i<n;i++) scanf("%d",a+i); for(int i=0;i<n;i++) scanf("%d",b+i); for(int l=0;l<n;l++) for(int r=l;r<n;r++) { ans=0; for(int i=l;i<=r;i++) ans+=a[i]-b[i]; minans=min(abs(ans),minans); if(minans==0) break; } cout<<minans; return 0; }
Algorithm(n2)
枚举l,枚举r;sum动态变化,minans打擂台
Code(20分)
#include<iostream>//不想OI一场空,千万别用万能头 #include<cstdio>//能不用cin就不用 #include<cstring> #include<map> #include<cmath> #define IL inline using namespace std; IL void fin(){freopen("choose.in","r",stdin);} IL void fout(){freopen("choose.out","w",stdout);} IL void fio() { fin(); fout(); } int n,a[300002],b[300002]; long long minans=0x3f3f3f3f3f,ans,l,r; int main() { fio(); cin>>n; for(int i=0;i<n;i++) scanf("%d",a+i); for(int i=0;i<n;i++) scanf("%d",b+i); for(l=0;l<n&&minans;l++) { for(r=l,ans=0;r<n&&minans;r++) { ans+=a[r]-b[r]; minans=min(abs(ans),minans); } } cout<<minans; return 0; }
Algorithm(nlog(n))
这才是重点……
一个suma存a的前缀和
一个sumb存b的前缀和
一个diff存suma-sumb
于是内存10MB起步
为了省空间
我又修改了一遍再提交;
在每个循环(i:1 to n)中,
suma[i]=sum[i-1]+a[i]
sumb[i]=sum[i-1]+b[i]
diff[i]=suma[i]-sumb[i]
=suma[i-1]+a[i]-(sumb[i-1]+b[i])
=suma[i-1]-sumb[i-1]+a[i]-b[i]
=diff[i-1]+a[i]-b[i]
于是我就省了许多空间(甚至连数组b都可以不要滴)
10MB->5MB
150ms->105ms
Code(100分)
//10MB部分即为注释 #include<iostream>//不想OI一场空,千万别用万能头 #include<algorithm>//快排sort() #include<cstdio>//能不用cin就不用 #include<cstring> #include<map> #define IL inline using namespace std; IL void fin(){freopen("choose.in","r",stdin);} IL void fout(){freopen("choose.out","w",stdout);} IL void fio() { fin(); fout(); } long long n,a[300001],b/*[300001]*/,ans,minans=0x3f3f3f,/*suma[300002],sumb[300002],*/diff[300001]; int main() { fio(); cin>>n; for(int i=1;i<=n;i++) { scanf("%lld",a+i); // suma[i]=suma[i-1]+a[i]; } for(int i=1;i<=n;i++) { scanf("%lld",&b/*+i*/); // sumb[i]=sumb[i-1]+b[i]; diff[i]=diff[i-1]+a[i]-b/*[i]*/; /* diff[i]=suma[i]-sumb[i]; diff[i]=suma[i-1]+a[i]-sumb[i-1]-b[i]; diff[i]=diff[i-1]+a[i]-b[i]; */ } sort(diff,diff+n+1); for(int i=1;i<=n;i++) minans=min(minans,abs(diff[i]-diff[i-1])); cout<<minans; return 0; }
Attention
sort从0开始!(就算diff只用了1~n)
因为diff可能保存负值
diff[0]=0 如果不参加排序,diff[1]-diff[0]岂不还是diff[0],与我们的目的偏离甚远?
不如就让0参加排序嘛
这也代表着:l==0时的情况
另外
数组和minans开long long!
数组和minans开long long!
数组和minans开long long!
否则满分80分,(扣20分起步)……