算法筆記_199:第二屆藍橋杯軟件類決賽真題(C語言本科)


 

前言:以下代碼部分僅供參考,C語言解答部分全部來自網友,Java語言部分部分參考自網友,對於答案的正確性不能完全保證。


 

試題1

 

數論中有著名的四方定理:所有自然數至多只要用四個數的平方和就可以表示。
我們可以通過計算機驗證其在有限范圍的正確性。

對於大數,簡單的循環嵌套是不適宜的。下面的代碼給出了一種分解方案。

請仔細閱讀,填寫空缺的代碼(下划線部分)。

注意:請把填空的答案(僅填空處的答案,不包括題面)存入考生文件夾下對應題號的“解答.txt”中即可。
直接寫在題面中不能得分。

int f(int n, int a[], int idx)
{
    if(______________) return 1;  // 填空1
    if(idx==4)  return 0;

    for(int i=(int)sqrt(n); i>=1; i--)
    {
        a[idx] = i;

        if(_______________________)  return 1;  // 填空2
    }

    return 0;
}

int main(int argc, char* argv[])
{
    for(;;)
    {
        int number;
        printf("輸入整數(1~10億):");
        scanf("%d",&number);
        
        int a[] = {0,0,0,0};

        int r = f(number, a, 0);

        printf("%d: %d %d %d %d\n", r, a[0], a[1], a[2], a[3]);
        
    }

    return 0;
}



a[0]*a[0] + a[1]*a[1] + a[2]*a[2] + a[3]*a[3] == n f(n, a, idx + 1) == 1
來自網友:

本題滿分: 9

 

  填空1: (3)

  n==0

  或者:0==n

 

  填空2: (6)

  f(n-i*i, a, idx+1)

  或者:

  f(n-i*i, a, idx+1) > 0

  f(n-i*i, a, idx+1) == 1

 

 

 

 

 


試題2

在對文本進行簡單加密的時候,可以選擇用一個n位的二進制數,對原文進行異或運算。
解密的方法就是再執行一次同樣的操作。

加密過程中n位二進制數會循環使用。並且其長度也可能不是8的整數倍。

下面的代碼演示了如何實現該功能。
請仔細閱讀,填寫空缺的代碼(下划線部分)。

void f(char* buf, unsigned char* uckey, int n)
{

    int i;
    for(i=0; i<n; i++)
        buf[i] = buf[i] ^ uckey[i];    //異或運算,即:buf[i] ^= uckey[i]
}

int main(int argc, char* argv[])
{
    char p[] = "abcd中國人123";  // 待加密串

    char* key = "11001100010001110";  //以串的形式表達的密匙,運算時要轉換為按位存儲的形式。

    int np = strlen(p);
    int nk = strlen(key);
    unsigned char* uckey = (unsigned char*)malloc(np);  // unsigned char是無符號字節型,char類型變量的大小通常為1個字節(1字節=8個位)    
    // 密匙串需要按位的形式循環拼入 uckey中
    int i;
    for(i=0; i<np*8; i++)
    {
        if(key[i%nk]=='1')
            ______;  // 填空1按位或
        else
            ______;  // 填空2按位與
    }
    
    f(p, uckey, strlen(p));
    f(p, uckey, strlen(p));

    printf("%s\n", p);

    free(uckey);

    return 0;
}


uckey[i/8] |= (unsigned char)0x80 >> (i%8) uckey[i/8] &= ~((unsigned char)0x80 >> (i%8))

本題滿分:14

  

  填空1(7)

  uckey[i/8] |= (unsigned char)0x80 >> (i%8);    //>>表示移位,位邏輯運算符:&按位與,|按位或,^按位異或,~取反移位運算符:<<左移,>>右移

從數學上看,左移1位等於乘以2,右移1位等於除以2,然后再取整,移位溢出的丟棄

 

  填空2(7)

  uckey[i/8] &= ~((unsigned char)0x80 >> (i%8));

 

  注意所有邏輯等價形式都是正確的答案,比如可以使用左移位:

  (unsigned char)0x80 >> 2  等價於:0x01 << 5

 

 

 

 

 


試題3

為什么1小時有60分鍾,而不是100分鍾呢?這是歷史上的習慣導致。
但也並非純粹的偶然:60是個優秀的數字,它的因子比較多。
事實上,它是1至6的每個數字的倍數。即1,2,3,4,5,6都是可以除盡60。

我們希望尋找到能除盡1至n的的每個數字的最小整數。

不要小看這個數字,它可能十分大,比如n=100, 則該數為:
69720375229712477164533808935312303556800

請編寫程序,實現對用戶輸入的 n (n<100)求出1~n的最小公倍數。

例如:
用戶輸入:
6
程序輸出:
60

用戶輸入:
10
程序輸出:
2520

要求考生把所有函數寫在一個文件中。調試好后,存入與考生文件夾下對應題號的“解答.txt”中即可。
相關的工程文件不要拷入。 
對於編程題目,要求選手給出的解答完全符合ANSI C標准,不能使用c++特性;
不能使用諸如繪圖、中斷調用等硬件相關或操作系統相關的API。

 

import java.math.BigInteger;
import java.util.Scanner;

public class Main {
    
    public void getResult(int n) {
        BigInteger temp1 = BigInteger.ONE;
        BigInteger temp2 = BigInteger.ONE;
        BigInteger temp3 = BigInteger.ONE;
        for(int i = 2;i <= n;i++) {
            temp1 = temp3;
            temp2 = new BigInteger(""+i);
            temp3 = temp1.gcd(temp2);
            temp3 = temp1.multiply(temp2).divide(temp3);
        }
        System.out.println(temp3);
    }
    
    public static void main(String[] args) {
        Main test = new Main();
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        test.getResult(n);
    }
}

 

來自網友C語言版:

解答:
最小公倍數就是所有質數的相應冪的積
比如N=10
小於10的質數有2,3,5,7
對應的最大冪是:3,2,1,1
則最小公倍數是:2^3x3^2x5^1x7^1 = 2520

 #include <iostream>
 #include <cstring>
 #include <cmath>
 using namespace std;
 
 int a[50] = {0};//存素數 
 bool vis[100];
 int b[50] = {0};//存冪次 
 
 void init_prim()//求小於100的所有素數存入數組a 
 {
      int i,j,k;
      int m = (int)(sqrt(100.0)+0.5);
      memset(vis,0,sizeof(vis));
      vis[0] = 1;
      vis[1] = 1;//必須加上,否則第一個素數別認為是1 
      for(i=2; i<=m; i++)
      if(!vis[i])
      {
           for(j=2*i; j<=100; j+=i)
                vis[j] = 1;
      }
      int t = 0;
      for(k=0; k<100; k++)
      if(!vis[k])
           a[t++] = k;
 }
      
 int main()
 {
      int i,j,k;
      init_prim();
      int n;
      //2^6 = 64,2^7 = 128;由於n最大100,冪次最大6 
     // for(i=0 ; i<100; i++)//素數沒問題 
     // if(!vis[i])
     //      cout<<i<<endl;
    //  while(1);
      while(cin>>n)
      {
           memset(b,0,sizeof(b));
           for(i=0; i<=n&&a[i]<=n; i++)//”1到n素數個數小於n的一半 “不對,3有兩個素數 
           {
               // cout<<a[i]<<"-----"<<endl;
                for(j=1; j<=6; j++)
                {
                     if(pow((double)a[i],(double)j)>(double)n)
                     {
                          b[i] = j -1;//b的下標不必新開  
                          break;
                     }
                     else if(pow((double)a[i],(double)j) == (double)n)//必須分開 
                     {
                           b[i] = j;
                          break;     
                     }
                }                                   
           }
           //不知道是不是pow函數的問題,把ans定義為int得出的結果出問題,double就對了 
           double ans = 1;
           for(k=0; k<i; k++)
           {
                //cout<<a[k]<<"........"<<b[k]<<endl;
                ans *= pow((double)a[k],(double)b[k]);
           }
           cout<<(int)ans<<endl;      
      }
      return 0;     
 }
 
 //該程序 到25時就溢出,ans換位long long前幾個就錯誤啦,此時需要把pow函數換掉

 #include <iostream>
 #include <cstdio>
 #include <cstring>
 #include <cmath>
 using namespace std;
 
 const int N = 105;
 int n;
 int a[N][50];
 int b[N] = {0};
 
 void multiply()
 {
     int i,j,k;
     memset(a,0,sizeof(a));
     for(i=3; i<=100; i++)
     {
         /*
         下面的是直接按平常的乘法,乘數的一位乘以被乘數的每一位並處理進位;另外是乘數整體乘以被乘數的每一位最后統一處理進位
         */
         int temp = 0; 
         a[i][0] = 1;//很重要 
         for(j=2; j<=i; j++)
         {
             int  c = 0; 
             for(k=0; k<50; k++)//最大不超過160位 ,目前是100!,最后除以3等50 
             {
                 temp = a[i][k]*b[j] + c;
                 a[i][k] = temp%1000;
                 c = temp/1000;
             }          
         }
     }
 }
 
 void printData(int n)
 {
     int i,j,k;
     for(i=49; i>=0; i--)
     if(a[n][i])
         break;
     cout<<a[n][i];//第一個不輸出前導0 
     for(j=i-1; j>=0; j--)
         printf("%03d",a[n][j]);
     cout<<endl;   
 }
 
 int main()
 {
     int i, j, k;
     for(i=0; i<N; i++)
             b[i] = i;
     for(i=2; i<N; i++)
         for(j=i+1; j<=N; j++)
         {
             if(b[j]%b[i]==0)
                 b[j] /= b[i];
             //cout<<b[j]<<endl;
         }
     //for(i=0; i<100; i++)
       //  cout<<b[i]<<endl;
     //while(1);
     multiply();
     
     while(cin>>n)
     {
         
         if(n==1||n==2)
         {
             cout<<n<<endl;
             continue;
         }
         
         printData(n);
     }
     return 0;
 }

 

 

 


試題4

為解決交通難題,某城市修建了若干條交錯的地鐵線路,線路名及其所屬站名如stations.txt所示。

線1
蘋果園
....
四惠東

線2
西直門
車公庄
....
建國門

線4
....

其中第一行數據為地鐵線名,接下來是該線的站名。
當遇到空行時,本線路站名結束。

下一行開始又是一條新線....直到數據結束。


如果多條線擁有同一個站名,表明:這些線間可以在該站換車。

為引導旅客合理利用線路資源,解決交通瓶頸問題,該城市制定了票價策略:

1. 每條線路可以單獨購票,票價不等。
2. 允許購買某些兩條可換乘的線路的聯票。聯票價格低於分別購票。

單線票價和聯合票價如 price.txt 所示。

線1 180
.....
線13 114
線1,線2 350
線1,線10 390
.....


每行數據表示一種票價
線名與票價間用空格分開。如果是聯票,線名間用逗號分開。
聯票只能包含兩條可換乘的線路。

現在的問題是:根據這些已知的數據,計算從A站到B站最小花費和可行的換乘方案。

比如,對於本題目給出的示例數據

如果用戶輸入:
五棵松,奧體中心

程序應該輸出:
-(線1,線10)-線8 = 565

如果用戶輸入:
五棵松,霍營

程序應該輸出:
-線1-(線4,線13) = 440

可以看出,用戶輸入的數據是:起始站,終到站,用逗號分開。
程序輸出了購票方案,在括號中的表示聯票,短橫線(-)用來分開乘車次序。
等號后輸出的是該方案的花費數值。


請編程解決上述問題。
注意:
1. 我們測試您的程序時,所用數據與題目中的示例數據不同,但格式完全一樣。
2. 當多個方案有相同的最小花費,輸出任意一個方案即可。


要求考生把所有類寫在一個文件中。
調試好后,存入與考生文件夾下對應題號的“解答.txt”中即可。
相關的工程文件不要拷入。請不要使用package語句。

 

對於此題,重點在於文本文件中信息的讀取,並選擇合適的數據結構來處理分類,好復雜的感覺,又看到相關備注,說明:此題類型在第四屆以后便不再用這種形式來出題,所以就簡單的看了一下網友的代碼,沒有自己上機實現。

Java版:藍橋杯-地鐵換乘

來自網友的C語言版:

  1 #include<iostream>
  2 using namespace std;
  3 #define LEN 50
  4 typedef struct stations{
  5     char name[20];
  6     int len;
  7     int roads[50];
  8     struct stations *left;
  9     struct stations *right;
 10 }Stations;
 11 
 12 typedef struct etree{
 13     int value;
 14     int roadNum;
 15     struct etree *father;
 16     int childnum;
 17 }ETree;
 18 
 19 typedef struct queue{
 20     ETree *tie;
 21     struct queue *next;
 22 }Queue;
 23 
 24 void pushQueue(Queue &head, ETree *&etree){
 25     Queue *p=head.next,*q=&head;
 26     while(p!=NULL &&  (p->tie->value<etree->value)){
 27         q=p;
 28         p=p->next;
 29     }
 30     q->next=(Queue*)malloc(sizeof(Queue));
 31     q->next->tie=etree;
 32     q->next->next=p;
 33 }
 34 void freeEtree(ETree *q){
 35     ETree *p;
 36     while(q->childnum==0){
 37         p=q;
 38         q=q->father;
 39         free(p);
 40         if(q!=NULL)
 41             q->childnum--;
 42         else
 43             break;
 44     }
 45 }
 46 
 47 void freeAll(Stations *&head){
 48     if (head!=NULL){
 49         freeAll(head->left);
 50         freeAll(head->right);
 51         free(head);
 52     }
 53 }
 54 
 55 void showBest(ETree *h,int price[][LEN],char roadName[][20],int roadNum){
 56     if(h!=NULL){
 57         if (h->faher==NULL){
 58             printf("%s",roadName[h->roadNum]);
 59         }
 60         else{
 61             int j;
 62             j=h->roadNum;
 63             if (h->value==(price[j][j]+h->father->value)){
 64                 showBest(h->father,price,roadName,roadNum);
 65                 if (price[j][roadNum]){
 66                     printf("-(%s,%s)",roadName[j],roadName[price[j][roadNum]-1]);
 67 
 68                 }
 69                 else
 70                     printf("-%s",roadName[j]);
 71             }
 72             else{
 73                 showBest(h->father->father,price,roadNme,roadNum);
 74                 printf("-(%s,%s)",roadName[h->father->roadNum],roadName[j]);
 75             }
 76         }
 77     }
 78 }
 79 
 80 inline int compares(char s1[],int n1,chr s2[],int n2){
 81     if (n1!=n2)
 82         return n1-n2;
 83     return strcmp(s1,s2);
 84 }
 85 boll findStation(Stations* &head,Stations* &p,char s[]){
 86     int len=strlen(s);
 87     int t;
 88     Stations q;
 89     p=head;
 90     while (n!=NULL){
 91         q=p;
 92         t=compares(s,len,p->name,p->len);
 93         if (t<0)
 94             p=p->left;
 95         else
 96             retrn true;
 97     }
 98     p=q;
 99     return false;
100 }
101 
102 void insert(Stations* &head,char s[],int road,int price[][LEN]{
103     Stations *p,*q;
104     int t;
105     t=strlen(s);
106     if(s[t-1]=='\n')
107         s[t-1]='\0';
108     if(head==NULL){
109         p=(Stations *)malloc(sizeof(Stations));
110         p->left=NULL;
111         p->rght=NULL;
112         strcpy(p->name,s);
113         p->len=strlen(s);
114         p->road[0]=1;
115         p->road[1]read;
116         head=p;
117     }
118     else{
119         if (findStation(head,p,s)){
120             p->roads[0]++;
121             t=p->roads[0];
122             p->roads[t]=road;
123             for(t--;t>0,t--){
124                 price[p->road[t]][road]=-1;
125                 price[road][p->road[t]]=-1;
126             }
127         }
128         else{
129             q=p;
130             p=(Stations *)malloc(sizeof(Stations));
131             p->left=NULL;
132             p->right=NULL;
133             strcpy(p->name,s);
134             p->len=strlen(s);
135             p->road[0]=1;
136             p->road[1]=road;
137             t=compares(s,p->len,q->name,q->len);
138             if(t<0)
139                 q->left=p;
140             else
141                 q->right=p;
142         }
143     }
144 }
145 
146 int GetRoadNum(char *r,char roadName[][20],int road Num){
147     for (int i=0;i<roadNum;i++)
148         if (strcmp(roadName[i],r)==0)
149             return i;
150         return 0;
151 }
152 
153 void main()
154 {
155     //[roadnum][roadnum+1]
156     int price[LEN][LEN]={0};
157     char roadName[LEN][20];
158     int i,j,k,t;
159     char line[20];
160     int roadNum;
161     Stations *head=NULL;
162     FILE *fp;
163     if((fp=fopen("stations.xt","r"))==NULL){
164         printf("找不到stations文件\n");
165         return;
166     }
167     roadNum=0;
168     while(!feof(fp)){
169         fscanf(fp,"%s%*c",roadName[roadNum]);
170         fgets(line,19,fp);
171         while(!feof(fp)&&line[0]!='\n'){
172             insert(head,line,roadNum,price);
173             fgets(line,19,fp);
174         }
175         roadNum++;
176     }
177     roadNum++;
178 }
179 insert(head,line,roadNum-1,price);
180 fclose(fp);
181 if ((fp=fopen("price.txt","r"))==NULL){
182     printf("找不到price文件");
183 }
184 while (!feof(fp)){
185     fscanf(fp,"%s,line);
186     fscanf(fp,"%d",&k);
187     for(t=0;line[t]!='\0'&&line[t]!=",";t++);
188     if (line[t]==','){
189         line[t]='\0';
190         i=GetRoadNum(line,roadName,roadNum);
191         j=GetRoadNum(line+t+1,roadName,roadNm);
192         price[i][j]=k;
193         price[j][i]=k;
194         if (price[i][i]>k){
195             price[i][roadNum]=j+1;
196         }
197         if (price[j][j]>k){
198             price[j][j]=k;
199             price[j]roadNum]=i+1;
200         }
201     }
202     else{
203         i=GetRoadNum(line,roadName,roadNum);
204         price[i][i]=k;
205     }
206 }
207 
208 fclose(fp);
209 
210 char starts[20]={"五棵松"},ends[20]="奧體中心"};
211 Stations *sroad,*eroad;
212 Queue Qhead, *h;
213 Etree *p,*q;
214 while(true){
215     char Flag[LEN]={0};//為-1表示目標,為0表示尚未發生過擴展
216     Qhead.next=NULL;
217     Qhead.tie=NULL;
218     scanf("%[^,\n]s",starts);
219     if (getchar()!=',')
220         break;
221     scanf("%[^\n]s",ends);
222     getchar();
223     if (!findStation(head,sroad,starts)){
224         printf("未找到%s的匹配項\n",starts);
225         continue;
226     }
227     if (!findStation(head,eroad,ends)){
228         printf("未找到%s的匹配項\n",ends);
229         continue;
230     }
231     for (i=1;i<=sroad->roads[0];i++){
232         p=(ETree*)malloc(sizeof(ETree));
233         p->father=NULL;
234         p->childnum=0;
235         p->roadNum=sroad->roads[i];
236         p->value=price[p->roadum][p->roadNum];
237         pushQueue(Qhead,p);
238     }
239     for (i=1;i<=eroad->roads[0];i++){
240         Flag[eroad->roads[i]]=-1;
241     }
242     while(Qhead.next!=NULL){
243         h=Qhead.next;
244         q=h->tie;
245         if (Flag[q->roadNum]==-1){
246             break;
247         }
248         Qhuad.next=Qhead.next->next;
249         i=q->roadNum;
250         if (Flag[i]!=1){
251             for(j=0;j<roadNum;j++){
252                 if (price[i][j]){
253                     q->childnum++;
254                     p=(ETree*)malloc(sizeof(ETree));
255                     p->father=q;
256                     p->childnum=0;
257                     p->roadNum=j;
258                     k=price[j][j]>0){
259                         if(price[i][j]>0){
260                             if(q->father!=NULL)
261                                 t=price[i][j]+q->father->value;
262                             else
263                                 t=price[i][j];
264                             if (k>t)
265                                 k=t;
266                         }
267                         p->value=k;
268                         pushQueue(Qhead,p);
269                     }
270                 }
271                 Flag[i]=1;
272             }
273             freeETree(h->tie);
274             free(h);
275         }
276         if (Qhead.next!=NULL){
277             showBest(q,price,roadName,roadNum);
278             printf("=%d\n",q->value);
279         }
280         else
281             printf("此路不通\n");
282         for(;Qhead.next!=NULL;){
283             h=Qead.next;
284             Qhead.nexQhead.next->next;
285             freeETree(h->tie);
286             free(h);
287         }
288     }
289     freeAll(head);
290 }

 

 

 


試題5

BMP是常見的圖像存儲格式。
如果用來存黑白圖像(顏色深度=1),則其信息比較容易讀取。

與之相關的數據:

(以下偏移均是從文件頭開始)
偏移:10字節, 長度4字節: 圖像數據真正開始的位置。
偏移:18字節, 長度4字節: 位圖的寬度,單位是像素。
偏移:22字節, 長度4字節: 位圖的高度,單位是像素。

從圖像數據開始處,每個像素用1個二進制位表示。
從圖片的底行開始,一行一行向上存儲。

Windows規定圖像文件中一個掃描行所占的字節數必須是4字節的倍數,
不足的位均以 0 填充。例如,圖片寬度為45像素,實際上每行會占用
8個字節。

可以通過Windows自帶的畫圖工具生成和編輯二進制圖像。
需要在“屬性”中選擇“黑白”,指定為二值圖像。
可能需要通過 查看 | 縮放 | 自定義... 把圖像變大比例一些,
更易於操作。

圖像的左下角為圖像數據的開始位置。白色對應1,黑色對應0

我們可以定義:兩個點距離如果小於2個像素,則認為這兩個點連通。
也就是說:以一個點為中心的九宮格中,圍繞它的8個點與它都是連通的。
如:t1.bmp 所示,左下角的點組成一個連通的群體;
而右上角的點都是孤立的。
      
            in.bmp                                t1.bmp
程序的目標是:根據給定的黑白位圖,分析出所有獨立連通的群體,
輸出每個連通群體的面積。所謂面積,就是它含有的像素的個數。

輸入數據固定存在in.bmp中。

如示例的in.bmp,
程序應該輸出:
12
81
52
133

該輸出表示:共有4個連通群體。
輸出的連通體面積間的順序可以隨意。

請編程解決上述問題。

我們測試程序的時候,會使用不同的in.bmp文件。


要求考生把所有類寫在一個文件中。
調試好后,存入與考生文件夾下對應題號的“解答.txt”中即可。
相關的工程文件不要拷入。請不要使用package語句。

                                圖 in.bmp

 

 

                                圖 t1.bmp

 這題要讀入圖片文件數據,感覺頭大啊,此前做的題,幾乎沒有遇到要讀取文件中的數據,而現在竟然還碰到了讀取圖片的數據,看到此題的核心:即使用DFS求取連通圖的問題,並且返回每一個連通圖中包含的頂點個數,但是對於此題處理讀取數據的問題,就沒有仔細去探究,下面貼出一段網友的C語言代碼,以作參考:

  1 include<stdio.h> 
  2 #include<stdlib.h> 
  3 #include<malloc.h> 
  4 #include<string.h> 
  5 
  6 void main(){ 
  7 int i,j,k,m; 
  8 int width,height,start,world; 
  9 int *bmp,*Lcount; 
 10 bool *Lflag; 
 11 FILE *fp; 
 12 if((fp=fopen("in1.bmp","rb"))==NULL){ 
 13 printf("文件打開失敗"); 
 14 return; 
 15 }
 16 fseek(fp,10L,0); 
 17 fscanf(fp,"%4c",&start); // 4c表示該數據占4個字節
 18 // printf("start = %d\n",start); 
 19 fseek(fp,18,0); 
 20 fscanf(fp,"%4c",&width); 
 21 // printf("width = %d\n",width); 
 22 fseek(fp,22,0); 
 23 fscanf(fp,"%4c",&height); 
 24 // printf("height = %d\n",height); 
 25 bmp = (int*)malloc((width+2)*sizeof(int)); 
 26 memset(bmp,0,(width+2)*sizeof(int)); 
 27 Lcount = (int*)malloc(width*sizeof(int)); 
 28 memset(Lcount,0,width*sizeof(int)); 
 29 Lflag = (bool*)malloc(width*sizeof(bool)); 
 30 memset(Lflag,0,width*sizeof(bool)); 
 31 Lcount--; 
 32 Lflag--; 
 33 fseek(fp,start,0); 
 34 world = ( width%32 ? width/32+1 : width/32 )*4; 
 35 int last,i1,i2,i3; 
 36 int eCount = 0 
 37 for(i=0 i<height i++ ){ 
 38 char c; 
 39 k=1; 
 40 last=0; 
 41 for(j=0 j<world j++){ 
 42 fscanf(fp,"%c",&c); 
 43 for(m = 7 m >= 0 && k<=width m-- ){ 
 44 if( !( 1<<m & c ) ){ 
 45 //printf("*"); 
 46 if(bmp[k]){ 
 47 last = bmp[k]; 
 48 Lcount[last]++; 
 49 Lflag[last] = true 
 50 }
 51 else{ 
 52 i1 = last ? last : bmp[k-1] 
 53 i3 = bmp[k+1] 
 54 last = 0; 
 55 if( i1 || i3){ 
 56 if( i1 && i3 && ( i1 != i3 ) ){//確定需要連接
 57 Lcount[i1] += Lcount[i3] 
 58 Lcount[i3]=0; 
 59 for(i2=1;i2<=width i2++){ 
 60 if(bmp[i2]==i3) 
 61 bmp[i2] = i1; 
 62 } 
 63 } 
 64 else{ 
 65 if(!i1) 
 66 i1=i3; 
 67 } 
 68 bmp[k] = i1 
 69 Lcount[i1]++; 
 70 Lflag[i1] = true 
 71 } 
 72 else{//插入
 73 for(i2=1;Lcount[i2];i2++); 
 74 Lcount[i2]=1; 
 75 bmp[k] = i2 
 76 Lflag[i2] = true 
 77 } 
 78 } 
 79 } 
 80 else{ //printf(" "); 
 81 last = bmp[k] 
 82 bmp[k] = 0 
 83 } 
 84 k++; 
 85 } 
 86 } 
 87 //printf("\n"); 
 88 for(i2=1;i2<=width;i2++){ 
 89 if(Lcount[i2] && !Lflag[i2] ){ 
 90 printf("%d\n",Lcount[i2]); 
 91 Lcount[i2] = 0 
 92 eCount++; 
 93 } 
 94 Lflag[i2]=false; 
 95 } 
 96 } 
 97 fclose(fp); 
 98 free(Lflag+1); 
 99 free(Lcount+1); 
100 free(bmp); 
101 printf("count=%d\n",eCount); 
102 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM