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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

算法竞赛入门经典(第二版) | 例题4-5 追踪电子表格中的单元格 (UVa512,Spreadsheet Tracking,World Finals)(解法二)

發(fā)布時(shí)間:2024/2/28 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法竞赛入门经典(第二版) | 例题4-5 追踪电子表格中的单元格 (UVa512,Spreadsheet Tracking,World Finals)(解法二) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本著清晰明了易懂可以水兩篇 的理念,筆者將這道題分兩次發(fā)布。這是第二種解法。


第一種解法傳送門→解法一+提交網(wǎng)址


因?yàn)?strong>解法1中有詳細(xì)關(guān)于題目和輸入輸出格式等的介紹,這里就不過多贅述了。

分析:

一些初學(xué)者做題的主要思路都是解法1:將題中每個(gè)可能的操作都考慮到,確保計(jì)算出所有可能的所有結(jié)果。
但解法2的思路相比上述有很大不同。
這個(gè)思路是將所有操作保存,然后對(duì)于每個(gè)查詢重新執(zhí)行每個(gè)操作,但不需要計(jì)算整個(gè)電子表格的變化,而只需關(guān)注所查詢的單元格的位置變化。不僅更好寫,且效率更高。
換句話說:我們的目標(biāo)是解決問題,而不是為了寫程序而寫程序,同時(shí)應(yīng)保持簡(jiǎn)單,而不是自己創(chuàng)造條件去展示編程技巧。

思路:

循環(huán)1:輸入3變量,r,c,n,進(jìn)入n個(gè)循環(huán)
循環(huán)2:輸入操作類型s、若為交換,則輸入4變量。若為其他,則輸入行/列數(shù),保存到數(shù)組。
還是循環(huán)2:輸入num個(gè)坐標(biāo),進(jìn)入函數(shù),先解決交換(Easy),若為插入,且插入行在坐標(biāo)行的前面,則最后輸出坐標(biāo)的行數(shù)+1,如果插入行等于坐標(biāo)行,則返回GONE; 若為刪除,且刪除行在坐標(biāo)行前面,則最后輸出的坐標(biāo)數(shù)減1;
返回,輸出。

代碼:

#include<stdio.h> #include<string.h> #define maxd 10000struct Command{char c[5];//保存指令int r1, c1, r2, c2;//交換的兩個(gè)坐標(biāo)int a, x[20];// a 為當(dāng)前指令行列變換操作次數(shù) x[20] 存儲(chǔ)的是相應(yīng)指令集合 }cmd[maxd];int r, c, n; //n為指令次數(shù)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坐標(biāo)變換情況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++;//(需要插入當(dāng)前行、列前面if(cmd[i].c[1] == 'C' && x <= *c0) dc++;//才會(huì)影響r0, c0)}else if(cmd[i].c[0] == 'D'){if(cmd[i].c[1] == 'R' && x == *r0) return 0;//刪除當(dāng)前行、列if(cmd[i].c[1] == 'C' && x == *c0) return 0;//時(shí)直接返回 0if(cmd[i].c[1] == 'R' && x < *r0) dr--;(同上注意刪除不能是本行列)if(cmd[i].c[1] == 'C' && x < *c0) dc--;}}*r0 += dr;//每組指令執(zhí)行完畢后 更新此時(shí) 坐標(biāo)狀況*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;}

收獲:

本題告訴我們,我們最終的目的是解題,而不是通盤考慮去展現(xiàn)算法技巧,所以我們只需關(guān)注與問題有關(guān)的變量,并將其過程化。


結(jié)語:
我們的目標(biāo)是解決問題,而不是為了寫程序而寫程序,同時(shí)應(yīng)保持簡(jiǎn)單,而不是自己創(chuàng)造條件去展示編程技巧。

總結(jié)

以上是生活随笔為你收集整理的算法竞赛入门经典(第二版) | 例题4-5 追踪电子表格中的单元格 (UVa512,Spreadsheet Tracking,World Finals)(解法二)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。