日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

《算法竞赛入门经典》习题4-2 正方形 (Squares,ACM,ICPC World Finals 1990,UVa201)——仅提供大体方法

發布時間:2024/4/30 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《算法竞赛入门经典》习题4-2 正方形 (Squares,ACM,ICPC World Finals 1990,UVa201)——仅提供大体方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原題及翻譯

A children’s board game consists of a square array of dots that contains lines connecting some of the pairs of adjacent dots.
兒童棋盤游戲由一組正方形的點組成,這些點包含連接一些相鄰點對的線。
One part of the game requires that the players count the number of squares of certain sizes that are formed by these lines.
游戲的一部分要求玩家計算由這些線組成的特定大小的方塊的數量。
For example, in the figure shown below, there are 3 squares— 2 of size 1 and 1 of size 2. (The “size” of a square is the number of lines segments required to form a side.)
例如,在下圖中,有3個正方形——2個邊長為1的和1個邊長為2的。(正方形的“大小”是構成一條邊所需的線段數。)

Your problem is to write a program that automates the process of counting all the possible squares.
您的問題是編寫一個程序來自動計算所有可能的正方形。

Input

輸入
The input file represents a series of game boards.
輸入文件表示一系列游戲板。
Each board consists of a description of a square array of n2 dots (where 2<=n<=9) and some interconnecting horizontal and vertical lines.
每個游戲板由一個由n2個點組成的正方形陣列(其中2<=n<=9)和一些相互連接的水平和垂直線組成。
A record for a single board with n2 dots and m interconnecting lines is formatted as follows:
帶有n2個點和m條連線的游戲板記錄格式如下:
Line 1: n the number of dots in a single row or column of the array
Line 2: m the number of interconnecting lines
第1行: n 陣列每一行或每一列中點的數目
第2行: m m條連線數量
Each of the next m lines are of one of two types:
接下來M條線都有兩種類型:
H i j indicates a horizontal line in row i which connects the dot in column j to the one to its right in column j + 1
H i j 表示第i行中連接J+1列中J列的圓點到其右側的圓點
or或
V i j indicates a vertical line in column i which connects the dot in row j to the one below in row j + 1
V i j 表示第i列中的一條垂直線上,將j行中的點與j+1行中的下一點連接起來。
Information for each line begins in column 1. The end of input is indicated by end-of-file. The first record of the sample input below represents the board of the square above.
每行的信息從第1列開始。輸入結束由文件結束指示。下面輸入的樣本的第一個記錄表示上面的方塊。

Output

輸出
For each record, label the corresponding output with ‘Problem #1’, ‘Problem #2’, and so forth.
對于每個記錄,用“問題1”、“問題2”等標記相應的輸出。
Output for a record consists of the number of squares of each size on the board, from the smallest to the largest.
記錄的輸出由板上每個數的平方數組成,從最小到最大。
lf no squares of any size exist, your program should print an appropriate message indicating so.
如果沒有任何大小的方塊存在,您的程序應該打印一個適當的消息來指示。
Separate output for successive input records by a line of asterisks between two blank lines, like in the sample below.
在兩個空白行之間用一行星號分隔連續輸入記錄的輸出,如下面的示例中所示。

Sample Input

樣例輸入
4
16
H 1 1
H 1 3
H 2 1
H 2 2
H 2 3
H 3 2
H 4 2
H 4 3
V 1 1
V 2 1
V 2 2
V 2 3
V 3 2
V 4 1
V 4 2
V 4 3
2
3
H 1 1
H 2 1
V 2 1

Sample Output

樣例輸出
Problem #1

2 square (s) of size 1
1 square (s) of size 2


Problem #2

No completed squares can be found.

思路分析

1.先把游戲板抽象出來,看成是一個二維數組,假設游戲板由n的平方個點組成,每個點都是二維數組中相隔一個元素的元素,中間的元素作為連線使用。
2.然后將二維數組元素全部初始化為0,然后將所有的點對應的元素都設置為1,中間連線為0。

3.錄入數據,根據數據內容將二維數組中對應的連線元素設置為1。

void Draw_line(char type,int index,int coordinate) {//根據輸入的數據將兩點之間的線連起來switch(type){case 'H':Game_board[2*index-1][2*coordinate]=1;break;case 'V':Game_board[2*coordinate][2*index-1]=1;break;} }

4.判斷邊長為n的正方形:
這讓我想到了汝佳老師前邊提到的蛇形填數的題目,只不過這道題只需要判斷一圈就可以。
從某一點出發,先向右走2n(n>1)個單位,判斷路徑上的數組元素是否都為1,然后向下再走2n(n>1)個單位,同上,以此類推。
如果中間有為0的元素,則回到第一個2n到達的點,如果能夠順利到達出發點,則邊長為n的正方形計數器+1,然后再回到第一個2n到達的點,或者從出發點再次出發走2(n+1)個單位。
這種方法是我一開始想到的,判斷起來比較麻煩,后來又想了一種比較簡單的方法:判斷以(i,j)為中心len為半邊長的正方形邊上的元素是否全為1,即正方形是否完全。

bool Judging_Squares(int n,int i,int j,int len) {//用于判斷以(i,j)為中心len為邊長的正方形是否成立if(i==1||j==1||i==n||j==n) return false;int flag=1;for(int a=i-len;a<i+len;a++){if(Game_board[a][j-len]!=1||Game_board[a][j+len]!=1)flag=0;}for(int a=j-len;a<j+len;a++){if(Game_board[i-len][a]!=1||Game_board[i+len][a]!=1)flag=0;}if(flag==1) return true;else return false; }

這兩部分就是主要的代碼了,剩下的就是讀入數據和使用函數進行操作,在main函數中進行。
主函數

int main() {//讀入數據并進行相應的操作和判斷int n,number,num=0;//n用于記錄棋盤的大小,number代表要讀入的數據行數,num用于判斷這是第幾次測試while(scanf("%d\n%d",&n,&number)==2){//讀入n和number并判斷是否讀入了兩個數據memset(Game_board,0,sizeof(Game_board));memset(squares,0,sizeof(squares));//將游戲板和計數正方形個數的數組初始化為0num++;for(int i=1;i<=2*n;i+=2){for(int j=1;j<=2*n;j+=2){Game_board[i][j]=1;//將游戲板根據n的大小將對應的點在二維數組中標記為1}}struct Types_of_lines tol[number];//聲明一個存儲連線類型的結構數組,結構會聲明為全局變量for(int i=0;i<number;i++){//讀入number行數據scanf("%c %d %d",&tol[i].type,&tol[i].index,&tol[i].coordinate);Draw_line(tol[i].type,tol[i].index,tol[i].coordinate);}for(int i=1;i<=2*n;i+=2){for(int j=1;j<=2*n;j+=2){for(int len=1;len<=n;len++){if(Judging_Squares(n,i,j,len))squares[len]++;}}}int flag=0;printf("Problem #%d\n\n",num);for(int len=n;len>0;len--){if(squares[len]){printf("%d square (s) of size %d\n",squares[len],len);flag=1;}}if(flag==0) printf("No completed squares can be found.\n");printf("\n**********************************\n\n");}return 0; }

在這里我要向看這篇文章的網友道歉,因為上面的代碼有錯誤,也就是因為這個錯誤,卡了我一下午。
第一個錯誤:在讀入數據的時候必須使用getchar()讀取空格,不然讀不了全部的數據。
第二個錯誤是將讀入的數據在Game_board描繪出來后用函數判斷是否為完全正方形的時候不能用+=2,必須得用++,不然會跳過一些邊長為1的正方形。

接下來是正確的答案。

完整代碼

#include <stdio.h> #include <string.h> void Draw_line(char type,int index,int coordinate); bool Judging_Squares(int n,int i,int j,int len); int Game_board[20][20]; int squares[10]; int main() {int n,number,num=0,index,coordinate;char type;while(scanf("%d\n%d",&n,&number)==2){memset(Game_board,0,sizeof(Game_board));memset(squares,0,sizeof(squares));num++;for(int i=1;i<=2*n;i+=2){for(int j=1;j<=2*n;j+=2){Game_board[i][j]=1;}}for(int i=0;i<number;i++){getchar();scanf("%c%d%d",&type,&index,&coordinate);Draw_line(type,index,coordinate);}for(int i=1;i<=2*n;i++){for(int j=1;j<=2*n;j++){for(int len=1;len<=n;len++){if(Judging_Squares(n,i,j,len))squares[len]++;}}}int flag=0;printf("Problem #%d\n\n",num);for(int len=n;len>0;len--){if(squares[len]){printf("%d square (s) of size %d\n",squares[len],len);flag=1;}}if(flag==0) printf("No completed squares can be found.\n");printf("\n**********************************\n\n");}return 0; } bool Judging_Squares(int n,int i,int j,int len) {//用于判斷以(i,j)為中心len為邊長的正方形是否成立int flag=1;for(int a=i-len;a<i+len;a++){if(Game_board[a][j-len]!=1||Game_board[a][j+len]!=1)flag=0;}for(int a=j-len;a<j+len;a++){if(Game_board[i-len][a]!=1||Game_board[i+len][a]!=1)flag=0;}if(flag==1) return true;else return false; } void Draw_line(char type,int index,int coordinate) {//根據輸入的數據將兩點之間的線連起來switch(type){case 'H':Game_board[2*index-1][2*coordinate]=1;break;case 'V':Game_board[2*coordinate][2*index-1]=1;break;} }

測試

感悟

做ACM的題真的要小心小心再小心,這道題題目給出的輸出格式就是一個坑,在處理輸入的數據的時候也要小心,重視getchar的使用。

每天磕一道ACM打卡 2月2日打卡

總結

以上是生活随笔為你收集整理的《算法竞赛入门经典》习题4-2 正方形 (Squares,ACM,ICPC World Finals 1990,UVa201)——仅提供大体方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。