[color=blue]
引用"月赛第一题(639题)【求真理】【呼唤管理员】!!!"原文(有改动)
BEGIN
大家先看一个程序:
var
s:array[0..10,0..10]of longint;
i:longint;
begin
s[1,0]:=1;
s[0,11]:=0;
writeln(s[1,0]);
end.
首先它不会范围检查出错。。
它的运行结果是0
开一个[0..n,0..m]的二维数组,[a,b]=[a+(b div m),b mod m]
相当于在PASCAL内部存储二维数组时是把下一行的下标接在这一行的后面,形成一个[0..n*m]的一维数组
…………所以
639题就出现了一个问题。。
再看一下这个程序:
var
a:array[0..101,0..101] of longint;
i,j,k,l,m,n,x1,y1,x2,y2,x3,y3,x4,y4,ans1,ans2,ans3:longint;
begin
readln(x1,y1,x2,y2,x3,y3,x4,y4);
for i:=x1+1 to x2 do
for j:=y1+1 to y2 do inc(a[i,j]);
for i:=x3+1 to x4 do
for j:=y3+1 to y4 do inc(a[i,j]);
//for i:=10 to 25 do begin for j:=10 to 25 do write(a[i,j]); writeln; end;
for i:=1 to 100 do
for j:=1 to 100 do
begin
if a[i,j]=0 then inc(ans3);
if a[i,j]=1 then inc(ans2);
if a[i,j]=2 then inc(ans1);
end;
writeln(ans1,' ',ans2,' ',ans3);
end.
状态: Unaccepted
测评机: Xeond[6]
得分: 90分
提交日期: 2011-8-27 18:13:00
有效耗时: 547毫秒
测试结果1: 通过本测试点|有效耗时156ms
测试结果2: 通过本测试点|有效耗时47ms
测试结果3: 测试结果错误.错误结果为:0 190 9810
正确结果应为:0 194 9806
测试结果4: 通过本测试点|有效耗时47ms
测试结果5: 通过本测试点|有效耗时47ms
测试结果6: 通过本测试点|有效耗时46ms
测试结果7: 通过本测试点|有效耗时47ms
测试结果8: 通过本测试点|有效耗时47ms
测试结果9: 通过本测试点|有效耗时63ms
测试结果10: 通过本测试点|有效耗时47ms
但当我们把数组开成[1..100,1..100]时,就AC了。
经wtttc套出数据,发现了一个问题
第三个点的输入数据超出了所给的数据范围—— 3 4 5 6 7 8 9 103(←103>100!!!)
END
[/color]
的确,第三个点的数据超出了所给的数据范围——0<=x1,y1,x2,y2,x3,y3,x4,y4<=100
而数据中出现了103
按理上面的算法不会出错
然而上面的程序,如果把数组开得再大一些,得出的又是不同的答案
于是,这就是一个答案输出的问题
(5-3)*(6-4)+(9-7)*(103-8)=194
题目中的菜地只有100*100
也就是超过100的部分不计算
所以不安全区域的面积应是10000-(194-3)=9811
但标准输出是9806,也就是说标准输出是用10000减去194得到的
其实正确的应该是用10000减去(194-超出100的部分的面积)。因为菜地只有100*100,所以超出的面积应该不算,题意大概是这意思
然而标准输出计算了超出部分的面积,因此导致了一个很大的误会
这题最好的方法其实是直接用if语句模拟。如果用数组,就会有上面的困惑。
?"其实正确的应该是用10000减去(194-超出100的部分的面积)。因为菜地只有100*100,所以超出的面积应该不算,题意大概是这意思
然而标准输出计算了超出部分的面积,因此导致了一个很大的误会"
??正确的到底是不是标准的
这种算法 完全避免
var
x:array[0..4] of longint;
y:array[0..4] of longint;
x1,x2,x3,x4,y1,y2,y3,y4,i,j,qsm,sm,nsm,t:longint;
begin
readln(x[1],y[1],x[2],y[2]);
readln(x[3],y[3],x[4],y[4]);
x1:=x[1];y1:=y[1];x2:=x[2];y2:=y[2];x3:=x[3];y3:=y[3];x4:=x[4];y4:=y[4];
if (x[2]<=x[3])and(y[2]<=y[3])then begin writeln('0 ',((x[2]-x[1])*(y[2]-y[1])+(x[4]-x[3])*(y[4]-y[3])),' ',10000-((x[2]-x[1])*(y[2]-y[1])+(x[4]-x[3])*(y[4]-y[3])));halt;end;
for i:=1 to 3 do
for j:=i+1 to 4 do
if x[i]>x[j] then begin t:=x[i];x[i]:=x[j];x[j]:=t;end;
for i:=1 to 3 do
for j:=i+1 to 4 do
if y[i]>y[j] then begin t:=y[i];y[i]:=y[j];y[j]:=t;end;
qsm:=(x[3]-x[2])*(y[3]-y[2]);
sm:=(x2-x1)*(y2-y1)+(x4-x3)*(y4-y3)-2*qsm;
nsm:=10000-sm-qsm;
writeln(qsm,' ',sm,' ',nsm);
end.