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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

【GDKOI2003】分球

發布時間:2025/3/15 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【GDKOI2003】分球 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Description
  在一個裝滿財寶的屋子里,有2N個盒子排成一排。除了兩個相鄰的空盒外,其余的每個盒子里都裝有一個金球或者一個銀球,總共有N-1個金球和N-1個銀球。以下是一個N=5時的例子,G表示金球,S表示銀球:
  
  任意兩個相鄰的非空的盒子里的球可以移動到兩個相鄰的空盒中,移動不能改變這兩個球的排列順序。寫一個程序,用最少的移動次數把所有的金球都移到所有銀球的左邊。

Input
  輸入文件包含多組數據。第一行為K,表示數據的總數。
  每組數據的第一行是N(3<=N<=7),第二行是2N個盒子的初始狀態。金球用a表示,銀球用b表示,空盒用空格表示。每兩組相鄰數據用空行隔開。

Output
  對于每一組數據,若無解則輸出一行-1,若有解,輸出最少移動次數,相鄰的兩組數據用一個空行隔開。

Sample Input
3
3
abab

5
abba abab

6
a babbababa

Sample Output
-1

3

4

Data Constraint
k<5
.
.
.
.
.

分析

可以直接用bfs來做,范圍小
對于普通的dfs,會死循環,考慮如何解決這個問題
我們想到對于一個格子只可能有三種情況:金、銀、空
那么我們可以用一個三進制數來壓縮狀態
.
.
.
.
.

程序:
#include <iostream> #include <string.h> #include <stdio.h> using namespace std; int k,n,head,tail,x,p,f[1600000],a[16],b[16],w[100000][16]; char zf;bool check(int *x) {int y=0;for (int i=1;i<=n+1;i++){y+=x[i]&1;if (y==n-1) return 1;if (x[i]==2) return 0;} }void work(int *x) {int c=0; p=0;for (int i=1;i<=2*n;i++)if (x[i]==0&&c==0) c=1; else p=p*3+x[i]; }int bfs() {if (check(w[1])) return 0;head=0;tail=1;work(w[1]);f[p]=k;while (head<tail){head++;memcpy(a,w[head],sizeof(a)); memcpy(b,a,sizeof(b)); b[0]++;for (int i=1;i<=2*n-1;i++) if (a[i]==0) {x=i;break;}for (int i=1;i<=2*n-1;i++) if (a[i]!=0&&a[i+1]!=0){b[x]=a[i];b[x+1]=a[i+1];b[i]=b[i+1]=0; work(b);if (f[p]!=k){if (check(b)) return b[0];tail++;f[p]=k; memcpy(w[tail],b,sizeof(w[tail]));}b[i]=a[i];b[i+1]=a[i+1];}}return -1; }int main() {cin>>k;while (k>0){cin>>n;getchar(); for (int i=1;i<=2*n;i++){zf=getchar();w[1][i]=(zf==' '?0:zf-96);}cout<<bfs()<<endl;k--;} }

轉載于:https://www.cnblogs.com/YYC-0304/p/9499922.html

總結

以上是生活随笔為你收集整理的【GDKOI2003】分球的全部內容,希望文章能夠幫你解決所遇到的問題。

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