1.1004 四子连棋
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 黄金 Gold
题目描述 Description
在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局。
● | ○ | ● | |
○ | ● | ○ | ● |
● | ○ | ● | ○ |
○ | ● | ○ |
输入描述 Input Description
从文件中读入一个4*4的初始棋局,黑棋子用B表示,白棋子用W表示,空格地带用O表示。
输出描述 Output Description
用最少的步数移动到目标棋局的步数。
样例输入 Sample Input
BWBO
WBWB
BWBW
WBWO
样例输出 Sample Output
5
1 #define N 5 2 #include<iostream> 3 using namespace std; 4 #include<cstdio> 5 char jz[N][N]; 6 struct Q{ 7 int x,y; 8 }q[2]; 9 int xx[]={1,-1,0,0}; 10 int yy[]={0,0,1,-1}; 11 long long sum=100;/*假设一个最大步数,一开始设定太大了,直接爆了栈空间*/ 12 int t=-1; 13 bool check() 14 { 15 for(int i=1;i<=4;++i) 16 { 17 char s=jz[i][1]; 18 bool biaozhi=true; 19 for(int j=2;j<=4;++j) 20 { 21 if(jz[i][j]!=s) 22 { 23 biaozhi=false; 24 break; 25 } 26 } 27 if(biaozhi) return true; 28 } 29 for(int i=1;i<=4;++i) 30 { 31 char s=jz[1][i]; 32 bool biaozhi=true; 33 for(int j=2;j<=4;++j) 34 { 35 if(jz[j][i]!=s) 36 { 37 biaozhi=false; 38 break; 39 } 40 } 41 if(biaozhi) return true; 42 } 43 bool biaozhi=true; 44 char s=jz[1][1]; 45 for(int i=2;i<=4;++i) 46 { 47 if(jz[i][i]!=s) 48 { 49 biaozhi=false; 50 break; 51 } 52 } 53 if(biaozhi) return true; 54 biaozhi=true; 55 s=jz[1][4]; 56 for(int i=2;i<=4;++i) 57 { 58 if(jz[i][5-i]!=s) 59 { 60 biaozhi=false; 61 break; 62 } 63 } 64 if(biaozhi) return true; 65 return false; 66 } 67 void dfs(bool fla,long long bushu) 68 { 69 if(bushu>=sum) return; 70 if(check()) 71 { 72 sum=min(sum,bushu); 73 return; 74 } 75 for(int i=0;i<2;++i) 76 { 77 for(int j=0;j<4;++j) 78 { 79 int x1=q[i].x+xx[j],y1=q[i].y+yy[j]; 80 if(x1>=1&&x1<=4&&y1>=1&&y1<=4) 81 { 82 if(fla&&jz[x1][y1]=='W') 83 { 84 swap(jz[x1][y1],jz[q[i].x][q[i].y]); 85 swap(x1,q[i].x); 86 swap(y1,q[i].y); 87 dfs(!fla,bushu+1); 88 swap(jz[x1][y1],jz[q[i].x][q[i].y]); 89 swap(x1,q[i].x); 90 swap(y1,q[i].y); 91 } 92 if(!fla&&jz[x1][y1]=='B') 93 { 94 swap(jz[x1][y1],jz[q[i].x][q[i].y]); 95 swap(x1,q[i].x); 96 swap(y1,q[i].y); 97 dfs(!fla,bushu+1); 98 swap(jz[x1][y1],jz[q[i].x][q[i].y]); 99 swap(x1,q[i].x); 100 swap(y1,q[i].y); 101 } 102 } 103 } 104 } 105 } 106 int main() 107 { 108 for(int i=1;i<=4;++i) 109 { 110 scanf("%s",jz[i]+1); 111 for(int j=1;j<=4;++j) 112 { 113 if(jz[i][j]=='O') 114 { 115 ++t; 116 q[t].x=i;q[t].y=j; 117 } 118 } 119 } 120 //swap(q[0],q[1]); 121 bool flag[]={true,false}; 122 for(int j=0;j<2;++j) 123 dfs(flag[j],0); 124 cout<<sum<<endl; 125 return 0; 126 }
2.1008 选数
2002年NOIP全国联赛普及组
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 黄金 Gold
1 /*顺便复习Miller_rabin算法*/ 2 #define N 21 3 #include<iostream> 4 using namespace std; 5 #include<cstdio> 6 #include<cstdlib> 7 #include<ctime> 8 typedef long long ll; 9 int a[N],n,k; 10 ll ans=0; 11 void input() 12 { 13 scanf("%d%d",&n,&k); 14 for(ll i=1;i<=n;++i) 15 scanf("%d",&a[i]); 16 } 17 ll quick_mod(ll a,ll b,ll c) 18 { 19 ll ans=1; 20 a%=c; 21 while(b) 22 { 23 if(b&1) 24 { 25 b--; 26 ans=(ans*a)%c;; 27 } 28 a=(a*a)%c; 29 b>>=1; 30 } 31 return ans; 32 } 33 bool Miller_rabin(ll n) 34 { 35 if(n==2) return true; 36 if(n<=1||!(n&1)) return false; 37 ll u=n-1,t=0; 38 while(!(u&1)) 39 { 40 u>>=1; 41 t++; 42 } 43 for(ll i=1;i<=10;++i) 44 { 45 ll x=rand()%(n-1)+1; 46 x=quick_mod(x,u,n); 47 for(ll j=0;j<t;++j) 48 { 49 ll y=quick_mod(x,2,n); 50 if(y==1&&x!=1&&x!=n-1) 51 return false; 52 x=y; 53 } 54 if(x!=1) return false; 55 } 56 return true; 57 } 58 void dfs(ll xh,ll sum,ll djg) 59 { 60 if(djg==k) 61 { 62 if(Miller_rabin(sum)) 63 ans++; 64 return; 65 } 66 if(n-xh<k-djg) return; 67 for(ll i=1;i<=n;++i) 68 { 69 if(xh+i<=n) dfs(xh+i,sum+a[xh+i],djg+1); 70 else break; 71 } 72 } 73 int main() 74 { 75 srand(time(0)); 76 input(); 77 for(ll i=1;i<=n-k+1;++i) 78 { 79 dfs(i,a[i],1); 80 } 81 cout<<ans<<endl; 82 return 0; 83 }
3.1005 生日礼物
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 黄金 Gold