1. 程式人生 > >演算法競賽入門經典(第二版)第三章陣列和字串例題與提示下

演算法競賽入門經典(第二版)第三章陣列和字串例題與提示下

  • 程式3-3蛇形填數

在nxn方陣裡填入1,2,……,nxn,要求填成蛇形。
例如,n=4時方陣為:
10 11 12 1
9 16 13 2
8 15 14 3
7 6 5 4
上面方陣中多餘空格只是為了便於觀察規律

  1. 可以用int a[max][max]生成一個整型的二維陣列,其中max和max不必相等。這個陣列共有max x max個元素,分別為a[0][1],a[0][1],……,a[0][max-1],a[1][0],a[1][1],……,a[1][max-1],……,a[max-1][0],a[max-1][1],……,a[max-1][max-1]。
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#define maxn 20
int a[maxn][maxn];
int main()
{
    int n,x,y,tot=0;
    scanf("%d",&n);
    memset(a,0,sizeof(a));
    tot=a[x=0][y=n-1]=1;//作為陣列a的下標
    while(tot<n*n)//原則時先判斷再移動而不是走了一步以後才發現越界了再退回來
    {
        while
(x+1<n&&a[x+1][y]==0) a[++x][y]=++tot; while(y-1>=0&&a[x][y-1]==0) a[x][--y]=++tot; while(x-1>=0&&a[x-1][y]==0) a[--x][y]=++tot; while(y+1<n&&a[x][y+1]==0) a[x][++y]=++tot; } for(x=0;x<n;x++) { for(y=0;y<n;y++)printf
("%d",a[x][y]); printf("\n"); } return 0; }
  1. 可以利用C語言簡潔的語法,但前提時保持程式碼的可讀性
  2. 在很多情況下,最好是在做一件事情之前檢查是不是可以做,而不要做完後再後悔。因為“悔棋”往往會比較麻煩

3.2字元陣列

  • 程式3-4豎式問題

找出形如 abc*de (三位數乘以兩位數) 的算式,使得在完整的豎式中,所有數字屬於一個特定的數字集合。輸入數字集合 (相鄰數字之間沒有空格),輸出所有豎式。每個豎式前應有編號,之後應有一個空行。最後輸出解的總數。
樣例輸入:
2357
樣例輸出:
<1>
…775
X…33
----
.2325
2325.
----
25575
The number of solutions = 1

本題的思路應該是很清晰的:嘗試所有的abcde,判斷是否滿足條件。我們可以寫出整個程式的虛擬碼
char s[20];
int count=0;
scanf("%s",s);
for(int abc=111;abc<=999;abc++)
for(int de=11;de<=99;de++)
if("abc
de"是個合法的豎式)
{
printf("<%d>\n",count);
列印abc*de的豎式和其後的空行
count++
}
printf(“The number of solutions =%d\n”,count);

  1. C語言中字元型用關鍵字char表示,它實際儲存的是字元的ASCII碼。字元常量可以用單引號表示。在語法上可以把字元當作Int型使用
  2. 在scanf("%s",s)和scanf("%d",&n)類似,它會讀入一個不含空格TAB和回車符的字串,不必在s前面加&符號。如果是字串陣列char s[max][max],可以用scanf("%s",s[i])提取第i個字串。
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int main()
{
    int count=0;
    char s[20],buf[99];
    scanf("%s",s);
    for(int abc=111;abc<=999;abc++)
        for(int de=11;de<=99;de++)
    {
        int x=abc*(de%10),y=abc*(de/10),z=abc*de;
        sprintf(buf,"%d%d%d%d%d",abc,de,x,y,z);//sprintf輸出到字串中
        int ok=1;
        for(int i=0;i<strlen(buf);i++)
            if(strchr(s,buf[i])==NULL) ok=0;//strchr函式是在一個字串中查詢單個字元
        if(ok)
        {
            printf("<%d>\n",++count);
            printf("%5d\nX%4d\n-----\n%5d\n%4d\n-----\n%5d\n\n",abc,de,x,y,z);
        }
    }
    printf("The number of solutions=%d\n",count);
}
  1. 可以用sprintf把資訊輸出到字串,用法和Printf,fprintf類似。但應當保證字串足夠大,可以容納輸出資訊
  2. C語言中的字串是以"\0"結尾的字元陣列,可以用strlen(s)返回字串s中結束標記之前的字元個數。字串中的各個字元是s[0],s[1],…,s[strlen(s)-1]。
  3. 由於字串的本質是陣列,它也不是“一等公民”,只能用strcpy(a,b),strcmp(a,b),strcat(a,b)來執行“賦值“,”比較“,”連線“操作,而不能用”=“,”==“,”<=“,"+"等運算子。上述函式在string.h宣告
  4. 濫用++,——,+=等可以修改變數值得運算子很容易帶來隱蔽得錯誤。建議每條語句最多隻用一次這種運算子,並且所修改得變數在整條語句中只出現一次。