CE_TAP @ 2023-11-17 19:53:25
代码爆RE了,不知道为什么
#include<iostream>
using namespace std;
#define int long long
int f[55][55][55];
int w(int a,int b,int c){
if(f[a][b][c]) return f[a][b][c];
if(a<=0 || b<=0 || c<=0) return 1;
if(a< b && b<c) return f[a][b][c]= w(a,b,c-1)+w(a,b-1,c-1)-w(a,b-1,c);
return f[a][b][c]= w(a-1,b,c)+w(a-1,b-1,c)+w(a-1,b,c-1)-w(a-1,b-1,c-1);
}
signed main(){
int a=0,b=0,c=0;
while(cin>>a>>b>>c){
if(a==-1 && b==-1 && c==-1){ return 0;}
printf("w(%lld, %lld, %lld) = ",a,b,c);
if(a>20 || b>20 ||c>20) a=b=c=20;
printf("%lld\n",w(a,b,c));
a=b=c=0;
}
return 0;
}
by rnf5114 @ 2023-11-17 20:03:01
@CE_TAP f数组开大点
by OldVagrant @ 2023-11-17 20:14:54
@CE_TAP 您的w函数里,第二个if应该放在第一个if之前。因为如果a,b,c三个数中有任何一个小于0,都会导致你访问到了f数组的负数下标。
by dontwannacry @ 2023-11-17 20:18:35
@CE_TAP
1.你的代码中:
if(f[a][b][c]) return f[a][b][c];
if(a<=0 || b<=0 || c<=0) return 1
但是值为负的数组下标会造成越界,导致了re 此处应将两行调换位置
2.这样改完后只有60分(WA on 5,7):注意题面中
但是你现在main()中先判了第二条再去w()中判第一条,所以WA了
AC code:
#include<iostream>
using namespace std;
#define int long long
int f[55][55][55];
int w(int a,int b,int c){
if(a<=0 || b<=0 || c<=0) return 1;
if(a>20 || b>20 ||c>20) a=b=c=20;
if(f[a][b][c]) return f[a][b][c];
//if(a<=0 || b<=0 || c<=0) return 1;
if(a< b && b<c) return f[a][b][c]= w(a,b,c-1)+w(a,b-1,c-1)-w(a,b-1,c);
return f[a][b][c]= w(a-1,b,c)+w(a-1,b-1,c)+w(a-1,b,c-1)-w(a-1,b-1,c-1);
}
signed main(){
int a=0,b=0,c=0;
while(cin>>a>>b>>c){
if(a==-1 && b==-1 && c==-1){ return 0;}
printf("w(%lld, %lld, %lld) = ",a,b,c);
//if(a>20 || b>20 ||c>20) a=b=c=20;
printf("%lld\n",w(a,b,c));
a=b=c=0;
}
return 0;
}
by CE_TAP @ 2023-11-17 20:24:33
@dontwannacry @OldVagrant @rnfmabj5114 感谢各位大佬