算法竞赛入门经典(第二版) | 例题4-5 追踪电子表格中的单元格 (UVa512,Spreadsheet Tracking,World Finals)(解法二)
本著清晰明了易懂可以水兩篇 的理念,筆者將這道題分兩次發布。這是第二種解法。
第一種解法傳送門→解法一+提交網址
因為解法1中有詳細關于題目和輸入輸出格式等的介紹,這里就不過多贅述了。
分析:
一些初學者做題的主要思路都是解法1:將題中每個可能的操作都考慮到,確保計算出所有可能的所有結果。
但解法2的思路相比上述有很大不同。
這個思路是將所有操作保存,然后對于每個查詢重新執行每個操作,但不需要計算整個電子表格的變化,而只需關注所查詢的單元格的位置變化。不僅更好寫,且效率更高。
換句話說:我們的目標是解決問題,而不是為了寫程序而寫程序,同時應保持簡單,而不是自己創造條件去展示編程技巧。
思路:
循環1:輸入3變量,r,c,n,進入n個循環
循環2:輸入操作類型s、若為交換,則輸入4變量。若為其他,則輸入行/列數,保存到數組。
還是循環2:輸入num個坐標,進入函數,先解決交換(Easy),若為插入,且插入行在坐標行的前面,則最后輸出坐標的行數+1,如果插入行等于坐標行,則返回GONE; 若為刪除,且刪除行在坐標行前面,則最后輸出的坐標數減1;
返回,輸出。
代碼:
#include<stdio.h> #include<string.h> #define maxd 10000struct Command{char c[5];//保存指令int r1, c1, r2, c2;//交換的兩個坐標int a, x[20];// a 為當前指令行列變換操作次數 x[20] 存儲的是相應指令集合 }cmd[maxd];int r, c, n; //n為指令次數int simulate(int *r0, int *c0){for(int i = 0; i < n; i++ ){if(cmd[i].c[0] == 'E'){//交換操作if(*r0 == cmd[i].r1 && *c0 == cmd[i].c1){*r0 = cmd[i].r2;*c0 = cmd[i].c2;}else if(*r0 == cmd[i].r2 && *c0 == cmd[i].c2){*r0 = cmd[i].r1;*c0 = cmd[i].c1;}}else if(cmd[i].c[0] != 'E'){int dr = 0,dc = 0;//記錄每組此操作r0, c0坐標變換情況for(int j = 0; j < cmd[i].a; j++ ){int x = cmd[i].x[j];if(cmd[i].c[0] == 'I'){if(cmd[i].c[1] == 'R' && x <= *r0 ) dr++;//(需要插入當前行、列前面if(cmd[i].c[1] == 'C' && x <= *c0) dc++;//才會影響r0, c0)}else if(cmd[i].c[0] == 'D'){if(cmd[i].c[1] == 'R' && x == *r0) return 0;//刪除當前行、列if(cmd[i].c[1] == 'C' && x == *c0) return 0;//時直接返回 0if(cmd[i].c[1] == 'R' && x < *r0) dr--;(同上注意刪除不能是本行列)if(cmd[i].c[1] == 'C' && x < *c0) dc--;}}*r0 += dr;//每組指令執行完畢后 更新此時 坐標狀況*c0 += dc;}}return 1; } int main(){// freopen("C:\\Users\\zhangwei\\Desktop\\input.txt","r",stdin); int r0, c0, q, kcase = 0;while(scanf("%d%d%d",&r,&c,&n) == 3 && r != 0){for(int i = 0; i < n; i++ ){scanf("%s",cmd[i].c);if(cmd[i].c[0] == 'E'){scanf("%d%d%d%d",&cmd[i].r1,&cmd[i].c1,&cmd[i].r2,&cmd[i].c2);}else{scanf("%d",&cmd[i].a);for(int j = 0; j < cmd[i].a; j++ ){scanf("%d",&cmd[i].x[j]);} }}if(kcase++)printf("\n");printf("Spreadsheet #%d\n",kcase);scanf("%d",&q);while(q--){scanf("%d%d",&r0, &c0);printf("Cell data in (%d,%d) ", r0, c0);if(!simulate(&r0, &c0))printf("GONE\n");elseprintf("moved to (%d,%d)\n", r0, c0); } }return 0;}收獲:
本題告訴我們,我們最終的目的是解題,而不是通盤考慮去展現算法技巧,所以我們只需關注與問題有關的變量,并將其過程化。
結語:
我們的目標是解決問題,而不是為了寫程序而寫程序,同時應保持簡單,而不是自己創造條件去展示編程技巧。
總結
以上是生活随笔為你收集整理的算法竞赛入门经典(第二版) | 例题4-5 追踪电子表格中的单元格 (UVa512,Spreadsheet Tracking,World Finals)(解法二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 算法竞赛入门经典(第二版) | 例题4-
- 下一篇: PTA 栈 (20分)(全网首发)(实现