1.6.4 棋盤問題2

      網友投稿 851 2025-03-31

      數據的第一行包含兩個正整數m,n,以一個空格分開,分別代表棋盤的大小,棋盤上有顏色的格子的數量。

      接下來的n 行,每行三個正整數x,y,c,分別表示坐標為(x,y)的格子有顏色c。

      其中c=1 代表黃色,c=0 代表紅色。相鄰兩個數之間用一個空格隔開。棋盤左上角的坐標為(1, 1),右下角的坐標為(m, m)。

      棋盤上其余的格子都是無色。保證棋盤的左上角,也就是(1,1)一定是有顏色的。

      輸出格式

      輸出一行,一個整數,表示花費的金幣的最小值,如果無法到達,輸出-1。輸入輸出樣例

      輸入樣例#1:

      5 7

      1 1 0

      1 2 0

      2 2 1

      3 3 1

      3 4 0

      4 4 1

      5 5 0

      輸出樣例#1:

      8

      輸入樣例#2:

      5 5

      1 1 0

      1 2 0

      2 2 1

      3 3 1

      5 5 0

      輸出樣例#2:

      -1

      說明

      輸入輸出樣例1

      說明

      從(1,1)開始,走到(1,2)不花費金幣

      從(1,2)向下走到(2,2)花費1 枚金幣

      從(2,2)施展魔法,將(2,3)變為黃色,花費2 枚金幣從(2,2)走到(2,3)不花費金幣

      從(2,3)走到(3,3)不花費金幣

      從(3,3)走到(3,4)花費1 枚金幣

      從(3,4)走到(4,4)花費1 枚金幣

      從(4,4)施展魔法,將(4,5)變為黃色,花費2 枚金幣,

      從(4,4)走到(4,5)不花費金幣

      從(4,5)走到(5,5)花費1 枚金幣

      共花費8 枚金幣。

      輸入輸出樣例2 說明

      從(1,1)走到(1,2),不花費金幣

      從(1,2)走到(2,2),花費1 金幣

      施展魔法將(2,3)變為黃色,并從(2,2)走到(2,3)花費2 金幣從(2,3)走到(3,3)不花費金幣

      從(3,3)只能施展魔法到達(3,2),(2,3),(3,4),(4,3)

      而從以上四點均無法到達(5,5),故無法到達終點,輸出-1

      數據規模與約定

      對于30%的數據,1 ≤m ≤5,1 ≤n ≤10。

      對于60%的數據,1 ≤m ≤20,1 ≤n ≤200。

      對于100%的數據,1 ≤m ≤100,1 ≤n ≤1,000。

      解題報告

      這道題目是2017年普及組第三題,實質上是求矩陣中一個點到另一個點的最短路徑,對于這類型的題目,通常可以用搜索的方法來完成,深度優先和廣度優先都行,廣度優先需要使用隊列,稍微復雜一點,我這里就用深搜來完成。

      1、輸入數據,構造棋盤,總共三種顏色,0表示紅色,1表示黃色,-1表示無色;

      2、從(1,1)點開始,往上下左右四個方向去搜索,這里和普通的只能往右和左搜索的題目有點不同,在普通的搜索里面,到達了一個點就設一個標志變量,然后下次就不再搜索這個節點,但是這里不能這么簡單的處理,因為每個節點可以往上下左右四個方向搜索,如果不設標志則會形成死循環,出不來,設個標志則有可能從不同的路徑走到這個點的花費可能不相同,第一次的花費不一定是最低的。那么我們就把進到這個節點的花費記錄下來,下次進入這個節點時候,比較一下花費,如果相同或者大于上次花費,就不用搜索這個節點,否則就繼續搜索他,我們把這種方法叫做記憶化搜索。

      3、對于魔法問題,我們采用一點貪心策略,碰到一個無色格子,就讓他變得和當前格子顏色一樣,再到深搜遞歸函數里面加上一個參數,來表示魔法狀態,如果上次已經使用了魔法,而當前格子是無色,也需要使用魔法,因為不能兩次使用魔法,就直接返回。

      4、當走到了右下角(m,m)點,說明已經找到了一條路徑,把花費最小那條路徑記錄下來就OK了。

      方法一:

      #include

      #include

      //本代碼可以把所有vis刪去,不影響運行結果

      //本代碼可以把所有vis刪去,不影響運行結果

      //本代碼可以把所有vis刪去,不影響運行結果

      int m,n;//棋盤大小,有色格子

      int map[101][101];//棋盤數據

      int step[4][2]={{1,0},{0,1},{-1,0},{0,-1}};//移動方向

      int ans=0xFFFFFFF;//答案,花費最少金幣數

      int d[101][101];//到達某個格子花費的最少金幣數

      int vis[101][101];//標記走過的格子

      //橫、縱坐標,是否使用過魔法,花費金幣總數

      void dfs(int x,int y,bool magic,int sum)

      {//如果這次走到(x,y)花的金幣不比之前搜索的少,必定不是最優解

      1.6.4 棋盤問題2

      if(sum>=d[x][y]) return;

      //否則更新最優解

      d[x][y]=sum;

      //判斷是否到終點,是則更新答案

      if(x==m && y==m){

      ans=std::min(sum,ans);

      return;

      }

      //否則開始枚舉往四個方向走

      int X,Y;

      for(int i=0;i<4;i++)

      {//計算下個格子坐標

      X=x+step[i][0];

      Y=y+step[i][1];

      //判斷下標越界,判斷重復訪問

      if(X<1||X>m||Y<1||Y>m||vis[X][Y]) continue;

      //如果是空格

      if(map[X][Y]==2){

      //如果上次使用過魔法,此路不通

      if(magic) continue;

      else {//上次沒用魔法,可以用

      vis[X][Y]=true;//標記

      //因為要花最少金幣,所以指定顏色和過來的格子一樣

      map[X][Y]=map[x][y];

      dfs(X,Y,true,sum+2);//走到下一個格子上

      map[X][Y]=2;//恢復空白

      }

      }

      //如果不是空格

      else if(map[X][Y]!=2){

      vis[X][Y]=true;//標記

      if(map[x][y]==map[X][Y]){//顏色相同

      dfs(X,Y,false,sum);

      }

      else dfs(X,Y,false,sum+1);//顏色不同

      }

      //回溯

      vis[X][Y]=false;

      }

      return;

      }

      int main()

      {//初始化

      for(int i=0;i<101;i++)

      {

      for(int j=0;j<101;j++)

      {

      map[i][j]=2;//全是空格

      d[i][j]=0xFFFFFFF;//全是最大值

      vis[i][j]=false;//全是未訪問

      }

      }

      scanf("%d%d",&m,&n);

      int x,y;

      while(n)

      {//給指定格子涂色

      scanf("%d%d",&x,&y);

      scanf("%d",&map[x][y]);

      --n;

      }

      vis[1][1]=true;//先行標記起點

      dfs(1,1,false,0);//傳初態

      if(ans!=0xFFFFFFF) printf("%d",ans);//如果有解

      else printf("-1");//如果無解

      return 0;

      }

      視頻接入服務 VIS

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:怎么對圖片自動編號(如何給圖片自動編號)
      下一篇:wps表格怎么平均分(wps表格平均分怎么操作)
      相關文章
      国产AV无码专区亚洲A∨毛片| 国产亚洲综合久久| 久久久久亚洲AV无码专区网站| 亚洲日韩AV无码一区二区三区人| 亚洲国产精品综合久久网各| 亚洲网址在线观看你懂的| 亚洲AV午夜成人片| 亚洲成色WWW久久网站| 亚洲国产精品无码一线岛国| 国产偷v国产偷v亚洲高清| 亚洲人成电影网站国产精品| 亚洲天堂中文字幕在线| 亚洲视频在线免费| 国产亚洲精品AA片在线观看不加载| 亚洲精品国产V片在线观看| 亚洲男人天堂2020| 久久亚洲国产成人精品无码区| 亚洲欧洲自拍拍偷精品 美利坚 | 亚洲一区二区三区国产精品| 爱情岛论坛网亚洲品质自拍| 国产亚洲欧洲Aⅴ综合一区 | 亚洲熟妇无码乱子AV电影| 亚洲一区无码中文字幕| 久久亚洲高清观看| 亚洲狠狠综合久久| 亚洲日本香蕉视频| 中日韩亚洲人成无码网站| 亚洲AV无码AV男人的天堂不卡| 综合偷自拍亚洲乱中文字幕| 亚洲精品WWW久久久久久| 亚洲一区二区三区偷拍女厕| 久久精品国产亚洲| 亚洲综合激情六月婷婷在线观看| 亚洲国产精品成人综合久久久| 国产精品亚洲精品| 国产亚洲一卡2卡3卡4卡新区| 亚洲精品人成无码中文毛片| 亚洲精品无码av人在线观看| 久久亚洲春色中文字幕久久久| 亚洲中文字幕无码av在线| 亚洲国产成人精品无码区花野真一|