1. 程式人生 > >論 C++ 在OpenJudge中做題的易錯點(一)

論 C++ 在OpenJudge中做題的易錯點(一)

論點一: Runtime Error

這個在OpenJudge中可能很常見,但最多的情況為:陣列開小了、執行時間過長(程式碼冗長、方法沒用對、情況考慮不到位以至於計算範圍得擴大)等等
例如:

狀態: Runtime Error
原始碼:
//此題解為 02:奇數單增序列

include<cstdio>
include<algorithm>
using namespace std;
int a[10],b[10];
int main()
{
    int m=0,x=0,y=0;
    int n;
    scanf("%d",&n);
    for(int
i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) { if(a[i]%2!=0) { x++; b[x]=a[i]; } } sort(b,b+x+1); for(int i=1;i<=x-1;i++) printf("%d,",b[i]); printf("%d",b[x]); }

修改後:

狀態: Accepted

#include<cstdio>
#include<algorithm> using namespace std; int a[5000],b[5000]; int main() { int m=0,x=0,y=0; int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) { if(a[i]%2!=0) { x++; b[x]=a[i]; } } sort(b,b+x+1
); for(int i=1;i<=x-1;i++) printf("%d,",b[i]); printf("%d",b[x]); }

察覺方法:1.注意讀題,一般在題中都會提到某些未知數的範圍,這時,我們就要注意,在開始寫程式碼的時候就將陣列大小調整好.也可以在程式碼寫完後再讀題、查錯(但不建議這麼做)。當然,還有一些‘懶豬’,在一開始時就將陣列開得特別大(比如說。。。我~),但是,雖說這麼做方便、快捷,但有時,還是會消耗許多時間,浪費許多空間。所以,我們都得一起努力,改掉這些壞習慣。(有則改之,無則加勉)
在最後,我再給大家舉一個典型的例子(陣列開小):

狀態: Runtime Error
原始碼
//此題為 7218:獻給阿爾吉儂的花束

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int f[400][400],n,m,i,j;
int head,tail,q[40005],p[40005],x,y,x1,y1,b[40005];
int xx[10]={-1,0,1,0},yy[10]={0,-1,0,1};
int main()
{   int l;
   scanf("%d",&l);
    while(l--)
     {
         scanf("%d%d",&m,&n);
        memset(f,0,sizeof(f));//清空 
        memset(b,0,sizeof(b));//清空 
        memset(p,0,sizeof(p));//清空 
        memset(q,0,sizeof(q));//清空 
        for (i=1;i<=m;i++)
           {
             char c[100];//***同志們注意看這裡***
             scanf("%s",c);//輸入矩陣 
             for(j=1;j<=n;j++)
            {
                if (c[j-1]=='.')
                  f[i][j]=1;
                if (c[j-1]=='#')
                  f[i][j]=0;
                if (c[j-1]=='S')
                  {
                    x=i; y=j;
                    f[i][j]=1;//並改為1 
                  }
                if (c[j-1]=='E')
                  {
                     x1=i; y1=j;
                     f[i][j]=1;
                  }
            }
           }
        head=0;tail=1;p[tail]=x;q[tail]=y;b[tail]=0;// i,j 初始位置 
        bool pd=0;
        while (head<tail)
         {
            head++;
            for(i=0;i<=3;i++)
             {
                int l=xx[i]+p[head];
                    int r=yy[i]+q[head];
                if (l>0&&l<=m&&r>0&&r<=n&&f[l][r]==1)
                  {
                      f[l][r]=0;
                      tail++;  
                        p[tail]=l; 
                        q[tail]=r; 
                        b[tail]=b[head]+1;
                  }
                if (l==x1&&r==y1)
                 {
                     cout<<b[tail]<<endl;
                     pd=1;
                     break;
                 }
              }
            if (pd==true)
                break;
         }
        if (pd==false)
         cout<<"oop!"<<endl;
     }}

修改後:

狀態: Accepted
原始碼

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int f[400][400],n,m,i,j;
int head,tail,q[40005],p[40005],x,y,x1,y1,b[40005];
int xx[10]={-1,0,1,0},yy[10]={0,-1,0,1};
int main()
{   int l;
   scanf("%d",&l);
    while(l--)
     {
         scanf("%d%d",&m,&n);
        memset(f,0,sizeof(f));//清空 
        memset(b,0,sizeof(b));//清空 
        memset(p,0,sizeof(p));//清空 
        memset(q,0,sizeof(q));//清空 
        for (i=1;i<=m;i++)
           {
             char c[4000];
             scanf("%s",c);//輸入矩陣 
             for(j=1;j<=n;j++)
            {
                if (c[j-1]=='.')
                  f[i][j]=1;
                if (c[j-1]=='#')
                  f[i][j]=0;
                if (c[j-1]=='S')
                  {
                    x=i; y=j;
                    f[i][j]=1;//並改為1 
                  }
                if (c[j-1]=='E')
                  {
                     x1=i; y1=j;
                     f[i][j]=1;
                  }
            }
           }
        head=0;tail=1;p[tail]=x;q[tail]=y;b[tail]=0;// i,j 初始位置 
        bool pd=0;
        while (head<tail)
         {
            head++;
            for(i=0;i<=3;i++)
             {
                int l=xx[i]+p[head];
                    int r=yy[i]+q[head];
                if (l>0&&l<=m&&r>0&&r<=n&&f[l][r]==1)
                  {
                      f[l][r]=0;
                      tail++;  
                        p[tail]=l; 
                        q[tail]=r; 
                        b[tail]=b[head]+1;
                  }
                if (l==x1&&r==y1)
                 {
                     cout<<b[tail]<<endl;
                     pd=1;
                     break;
                 }
              }
            if (pd==true)
                break;
         }
        if (pd==false)
         cout<<"oop!"<<endl;
     }}

當然,陣列開小並不是唯一的錯誤,像執行時間過長(程式碼冗長、方法沒用對、情況考慮不到位以至於計算範圍得擴大)這些問題還是存在的,但這些問題的解決方案也還是隻有自己,修改程式碼。就像在做廣搜的題時,你用深搜的方法去做,一一列舉,如此,就有可能時間超限。