1. 程式人生 > >【POJ1321棋盤問題】【poj2251Dungeon Master】【poj3278Catch That Cow】【poj1426Find The Multi】

【POJ1321棋盤問題】【poj2251Dungeon Master】【poj3278Catch That Cow】【poj1426Find The Multi】

POJ1321棋盤問題
題意:在一個給定形狀的棋盤(形狀可能是不規則的)上面擺放棋子,棋子沒有區別。要求擺放時任意的兩個棋子不能放在棋盤中的同一行或者同一列,請程式設計求解對於給定形狀和大小的棋盤,擺放k個棋子的所有可行的擺放方案C。
 Input
 輸入含有多組測試資料.每組資料的第一行是兩個正整數n k,用一個空格隔開,表示了將在一個n*n的矩陣內描述棋盤,以及擺放棋子的數目.n<= 8,k<= n 
當為-1 -1時表示輸入結束。 
隨後的n行描述了棋盤的形狀:每行有n個字元,其中 # 表示棋盤區域, . 表示空白區域(資料保證不出現多餘的空白行或者空白列)。 
Output
對於每一組資料,給出一行輸出,輸出擺放的方案數目C (資料保證C<2^31).
Sample Input
2 1
 # .
 . #
 
4 4
 . . . #
 . . # .
 . # . .
 # . . .
-1 -1
Sample Output
2
1

#include <iostream>
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
int n,k;
char map[10][10];
int vis[10];
int ans,cnt;
void dfs(int x){
    if(cnt==k){
        ans++;
        return ;
    }
    if(x>n)return ;
    for(int i=1;i<=n;++i){
        if(x>=1&&x<=n&&map[x][i]=='#'&&!vis[i]){
            cnt++;vis[i]=1;
            dfs(x+1);
            cnt--;vis[i]=0;
        }
    }
    dfs(x+1);
    return ;
}
int main(){
    while(scanf("%d%d",&n,&k)){
        if(n==-1||k==-1){
            break;
        }
        for(int i=1;i<=n;++i)
                scanf("%s",map[i]+1);
    memset(vis,0,sizeof(vis));
    ans=0,cnt=0;
    dfs(1);
    cout<<ans<<endl;
    }
    return 0;
}

POJ2251
題目大意:給一個三維圖,可以前後左右上下6種走法,走一步1分鐘,求最少時間(其實就是最短路)
分析:DFS的話複雜度為O(6^n)會TLE)

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
using namespace std;
char map[35][35][35];
int vis[35][35][35];
int X,Y,Z,sx,sy,sz,ex,ey,ez;
int dir[6][3] = {{0,0,1},{0,0,-1},{0,1,0},{0,-1,0},{1,0,0},{-1,0,0}};
 int step[35][35][35];
struct node
{
    int x,y,z;
};
int bfs()
{
    node p,next;
    queue<node> Q;
    p.x = sx,p.y = sy,p.z = sz;

    step[sx][sy][sz]=0;
    vis[sx][sy][sz] = 1;
    Q.push(p);
    while(!Q.empty())
    {
        p = Q.front();
        Q.pop();
         if(map[p.x][p.y][p.z]=='E')
            return step[ex][ey][ez];//p.step;
        vis[p.x][p.y][p.z]=1;
        for(int i = 0; i<6; i++)
        {

            int dx = p.x+dir[i][0];
            int dy = p.y+dir[i][1];
            int dz = p.z+dir[i][2];
            //if(check(next.x,next.y,next.z))
           	if(vis[dx][dy][dz]||map[dx][dy][dz]=='#'||dx<0||dx>=X||dy<0||dy>=Y||dz<0||dz>=Z)
                continue;
            vis[dx][dy][dz] = 1;
            next.x=dx,next.y=dy,next.z=dz;
            step[dx][dy][dz]=step[p.x][p.y][p.z]+1;//next.step = p.step+1;
            Q.push(next);
        }
    }
    return 0;
}

int main()
{
    int i,j,r;
    while(scanf("%d%d%d",&X,&Y,&Z),X+Y+Z)
    {
        for(i = 0; i<X; i++)
        {
            for(j = 0; j<Y; j++)
            {
                scanf("%s",map[i][j]);
                for(r = 0; r<Z; r++)
                {
                    if(map[i][j][r] == 'S')
                    {
                        sx = i,sy = j,sz = r;
                    }
                    else if(map[i][j][r] == 'E')
                    {
                        ex = i,ey = j,ez = r;
                    }
                }
            }
        }
        memset(vis,0,sizeof(vis));
        int ans;
        ans = bfs();
        if(ans)
            printf("Escaped in %d minute(s).\n",ans);
        else
            printf("Trapped!\n");
    }

    return 0;
}

POJ3278  Catch That Cow
FJ要抓奶牛。
       開始輸入N(FJ的位置)K(奶牛的位置)。
        FJ有三種移動方法:1、向前走一步,耗時一分鐘。
                          2、向後走一步,耗時一分鐘。
                          3、向前移動到當前位置的兩倍N*2,耗時一分鐘。
問FJ抓到奶牛的最少時間。奶牛不會動。

#include<iostream>
#include<queue>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn=100001;
bool vis[maxn];
int step[maxn];
void bfs(int n,int k)
{
    memset(step,0,sizeof(step));
    memset(vis,false,sizeof(vis));
    queue <int> q;
    int p,tmp;
    q.push(n);
    step[n]=0;
    vis[n]=true;
    while(!q.empty())  {
        p=q.front();
        q.pop();
        if(p==k){printf("%d\n",step[p]);return ;}
        for(int i=0;i<3;i++)     {
            if(i==0) tmp=p-1;
            else if(i==1) tmp=p+1;
            else tmp=p*2;
            if(tmp<0 || tmp>=maxn) continue;
            if(!vis[tmp])  {
                q.push(tmp);
                step[tmp]=step[p]+1;
                vis[tmp]=true;
            }
        }
    }
}
int main()
{
    int n,k;
    while(scanf("%d%d",&n,&k)!=EOF){
        if(n>=k) printf("%d\n",n-k);
        else
        bfs(n,k);
    }
    return 0;
}

POJ1426   給一個數n,讓你找出一個只有1,0,組成的十進位制數,要求是找到的數可以被n整除。

 #include <iostream>
 #include<cstdio>
 #include <iostream>
 #include <cstring>
 #include <queue>
 #include<iostream>
 #include<cstdlib>
 #include<cstdio>
 #include<cstring>
 #include<queue>
 #include<algorithm>
 #include<cmath>
 using namespace std;
 typedef long long ll;
 const int maxn=1e6+10;
 int n;
void bfs(){
	queue<ll> q;
	ll tmp;
	q.push(1);
	while(!q.empty()){
		tmp=q.front();
			q.pop();
		if(tmp%n==0)
		{
			printf("%lld\n",tmp);
			return ;
		}
		q.push(tmp*10);
		q.push(tmp*10+1);
	}
}
int main(){
	while(scanf("%d",&n)!=EOF){
		if(n==0)break;
		bfs();
	}
	return 0;
}