顯示具有 DFS 標籤的文章。 顯示所有文章
顯示具有 DFS 標籤的文章。 顯示所有文章

2012年9月20日 星期四

uva 10422 - Knights in FEN


Problem D

Knights in FEN

Input: standard input
Output: standard output
Time Limit: 10 seconds

There are black and white knights on a 5 by 5 chessboard. There are twelve of each color, and there is one square that is empty. At any time, a knight can move into an empty square as long as it moves like a knight in normal chess (what else did you expect?).
Given an initial position of the board, the question is: what is the minimum number of moves in which we can reach the final position which is:
Input
First line of the input file contains an integer N (N<14 are="are" below:="below:" description="description" each="each" given="given" how="how" indicates="indicates" inputs="inputs" is="is" many="many" of="of" p="p" set="set" sets="sets" that="that" the="the" there.="there.">
Each set consists of five lines; each line represents one row of a chessboard. The positions occupied by white knights are marked by 0 and the positions occupied by black knights are marked by 1. The space corresponds to the empty square on board.
There is no blank line between the two sets of input.
The first set of the sample input below corresponds to this configuration:
Output
For each set your task is to find the minimum number of moves leading from the starting input configuration to the final one. If that number is bigger than 10, then output one line stating
Unsolvable in less than 11 move(s).

otherwise output one line stating
Solvable in n move(s).
where n <= 10.
The output for each set is produced in a single line as shown in the sample output.

Sample Input

2
01011
110 1
01110
01010
00100
10110
01 11
10111
01001
00000

Sample Output

Unsolvable in less than 11 move(s).
Solvable in 7 move(s).


(Problem Setter: Piotr Rudnicki, University of Alberta, Canada)


“A man is as great as his dreams.”

 DFS+ bitmask + backtracking

#include<stdio.h>
#include<cstring>
#include<string>
#include<vector>
#include<set>
#include<queue>
#define REP(i, b, n) for (int i = b; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define DBG 0
using namespace std;

struct Node{
    Node(){}
    Node(int a,int b,int c):val(a),row(b),col(c){}
    int val,row,col;
    bool operator <(Node b)const{return val<b.val||row<b.row||col<b.col;}
};
int T,bnum=13;
set<Node>st;
int bottom[]= {5,10,11,12,15,16,17,18,20,21,22,23,24};
char chess[5][10],dir[8][2];
void init(){
    rep(i,5)T<<=1,T+=1;
    T<<=1;
    rep(i,4)T<<=1,T+=1;
    rep(i,3)T<<=1; rep(i,2)T<<=1,T+=1;
    rep(i,4)T<<=1;T<<=1,T+=1;
    rep(i,5)T<<=1;
    dir[0][0]=-2,dir[0][1]=-1,
    dir[1][0]=-2,dir[1][1]=1,
    dir[2][0]=-1,dir[2][1]=-2,
    dir[3][0]=-1,dir[3][1]=2,
    dir[4][0]=1,dir[4][1]=-2,
    dir[5][0]=1,dir[5][1]=2,
    dir[6][0]=2,dir[6][1]=-1,
    dir[7][0]=2,dir[7][1]=1;
}
void getHole(int &a,int &b){
    rep(i,5)rep(j,5)if(chess[i][j]==' ')a=i,b=j;
}
bool getH(int a,int b){
    return (a>>24-b)%2;
}
int setH(int a,int pos,int b){
    if(b)a|=1<<(24-pos);
    else a-=(a & (1<<(24-pos)) );
    return a;
}
int count(int c){
    int a=0;
    rep(i,bnum){if(getH(c,bottom[i]))a++;}
    if(DBG)printf("cnt: %d\n",a);
    return a;
}
int getC(){
    int c=0;
    rep(i,5)rep(j,5){
        if(chess[i][j]=='1')c<<=1,c+=1;
        else c<<=1;
    }
    return c;
}
int move(int v,int cr,int cc,int nr,int nc){
    int from=cr*5+cc,to=nr*5+nc;
    int h=getH(v,from);
    v=setH(v,from,0);
    v=setH(v,to,h);         //move
    return v;
}
bool valid(int a,int b){return a>=0&&a<5&&b>=0&&b<5;}
void print(int a){
    rep(i,5){
        rep(j,5)printf("%d",getH(a,i*5+j));
        printf("\n");
    }
}
void ans(){
    int cur,dis,next,cr,cc,nr,nc;
    bool h;
    Node nd;
    int res=11;
    st.clear();
    getHole(cr,cc);
    queue<pair<Node,int> >q;
    nd=Node(getC(),cr,cc);
    st.insert(nd);
    q.push(make_pair(nd,0));
    while(q.size()){
        cur=q.front().first.val,dis=q.front().second,
        cr=q.front().first.row,cc=q.front().first.col;
        if(DBG){printf("cur\n");print(cur);printf("cur cr cc dis %d %d %d %d\n",cur,cr,cc,dis);}
        q.pop();
        if(dis>10)break;
        if(count(cur)>10-dis)continue;
        if(cur==T&&cr==2&&cc==2){res=dis;break;}
        rep(i,8){
            nr=cr+dir[i][0],nc=cc+dir[i][1];
            if(valid(nr,nc)){
                if(DBG)printf("new hole %d %d\n",nr,nc);
                next=move(cur,nr,nc,cr,cc);
                nd=Node(next,nr,nc);
                if(!st.count(nd))
                    st.insert(nd),q.push(make_pair(Node(next,nr,nc),dis+1));
            }
        }
    }
    if(res>10)printf("Unsolvable in less than 11 move(s).\n");
    else printf("Solvable in %d move(s).\n",res);
}
int main(){
    int n;
    scanf("%d ",&n);
    init();
    rep(i,n){
        rep(i,5)fgets(chess[i],10,stdin);
        ans();
    }
}

uva 10400 - Game Show Math


Problem H
Game Show Math
Input: standard input
Output: standard output
Time Limit: 15 seconds
A game show in Britain has a segment where it gives its contestants a sequence of positive numbers and a target number. The contestant must make a mathematical expression using all of the numbers in the sequence and only the operators: +, -,*, and, /. Each number in the sequence must be used exactly once, but each operator may be used zero to many times. The expression should be read from left to right, without regard for order of operations, to calculate the target number. It is possible that no expression can generate the target number. It is possible that many expressions can generate the target number.
There are three restrictions on the composition of the mathematical expression:
o  the numbers in the expression must appear in the same order as they appear in the input file
o  since the target will always be an integer value (a positive number), you are only allowed to use / in the expression when the result will give a remainder of zero.
o  you are only allowed to use an operator in the expression, if its result after applying that operator is an integer from (-32000 .. +32000).
Input
The input file describes multiple test cases. The first line contains the number of test cases n.
Each subsequent line contains the number of positive numbers in the sequence p, followed by p positive numbers, followed by the target number. Note that 0 < p £ 100. There may be duplicate numbers in the sequence. But all the numbers are less than 32000.
Output
The output file should contain an expression, including all k numbers and (k-1) operators plus the equals sign and the target. Do not include spaces in your expression. Remember that order of operations does not apply here. If there is no expression possible output "NO EXPRESSION" (without the quotes). If more than one expression is possible, any one of them will do.

Sample Input
3
3 5 7 4 3
2 1 1 2000
5 12 2 5 1 2 4
Sample Output
5+7/4=3
NO EXPRESSION
12-2/5*1*2=4

(Problem-setter: Sandy Graham, CS Dept, University of Waterloo)

DFS + backtracking


#include<stdio.h>
#include<cstring>
#include<string>
#include<vector>
#define REP(i, b, n) for (int i = b; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define DBG 0
using namespace std;

int N,T,data[100];
bool trav[100][64001];
string res;
bool valid(int a){return a>=-32000&&a<=32000;}
bool DFS(int ind,int num,string s){
if(DBG)printf("dfs ind num %d %d\n",ind ,num);
if(ind==N){
if(num==T){res=s;return 1;}
return 0;
}
if(trav[ind][num+32000])return 0;
trav[ind][num+32000]=1;
if(valid(num+data[ind])&&DFS(ind+1,num+data[ind],s+'+'))return 1;
if(valid(num-data[ind])&&DFS(ind+1,num-data[ind],s+'-'))return 1;
if(valid(num*data[ind])&&DFS(ind+1,num*data[ind],s+'*'))return 1;
if(data[ind]!=0&&num%data[ind]==0&&valid(num*data[ind])&&DFS(ind+1,num/data[ind],s+'/'))return 1;
return 0;
}
void print(){
printf("%d",data[0]);
rep(i,res.size()){
printf("%c%d",res[i],data[i+1]);
}
printf("=%d\n",T);
}
void ans(){
int tot=0;
memset(trav,0,sizeof(trav));
if(DFS(1,data[0],""))print();
else printf("NO EXPRESSION\n");
}
int main(){
int n;
scanf("%d",&n);
rep(i,n){
scanf("%d",&N);
rep(i,N)scanf("%d",&data[i]);scanf("%d",&T);
if(DBG)printf("T %d\n",T);
ans();
}
}

uva 10344 - 23 Out of 5


Problem I
23 Out of 5
Input: standard input
Output: standard output
Time Limit: 1 second
Memory Limit: 32 MB
Your task is to write a program that can decide whether you can find an arithmetic expression consisting of five given numbers (1<=i<=5) that will yield the value 23.
For this problem we will only consider arithmetic expressions of the following from:
 
where : {1,2,3,4,5} -> {1,2,3,4,5} is a bijective function
and  {+,-,*} (1<=i<=4)

Input

The Input consists of 5-Tupels of positive Integers, each between 1 and 50.
Input is terminated by a line containing five zero's. This line should not be processed.

Output

For each 5-Tupel print "Possible" (without quotes) if their exists an arithmetic expression (as described above) that yields 23. Otherwise print "Impossible".

Sample Input

1 1 1 1 1
1 2 3 4 5
2 3 5 7 11
0 0 0 0 0

Sample Output

Impossible
Possible
Possible

Thomas Strohmann

DFS +backtracking


#include<stdio.h>
#include<cstring>
#include<string>
#include<vector>
#define REP(i, b, n) for (int i = b; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define DBG 0
using namespace std;

int data[5];
bool used[5];
bool DFS(int ind,int num,int len,int left){
if(DBG)printf("dfs: ind num %d %d\n",ind,num);
int b;
if(len==5)return num==23;
if(num-23>left){if(DBG)printf("len num left %d %d %d\n",len,num,left);return 0;}
used[ind]=1;
rep(i,5){
if(!used[i]){
b=left-data[i];
if(DFS(i,num+data[i],len+1,b))return 1;
if(DFS(i,num-data[i],len+1,b))return 1;
if(DFS(i,num*data[i],len+1,b))return 1;
}
}
used[ind]=0;
return 0;
}
void ans(){
int tot=0;
rep(i,5)tot+=data[i];
memset(used,0,sizeof(used));
rep(i,5)if(DFS(i,data[i],1,tot-data[i])){printf("Possible\n");return;}
printf("Impossible\n");
}
int main(){
int a,i;
while(scanf("%d%d%d%d%d",&data[0],&data[1],&data[2],&data[3],&data[4])==5){
for(i=0;i<5;i++)if(data[i]>0)break;
if(i==5)break;
ans();
}
}

10285 - Longest Run on a Snowboard


Problem C
Longest Run on a Snowboard
Input: standard input
Output: standard output
Time Limit: 5 seconds
Memory Limit: 32 MB

Michael likes snowboarding. That's not very surprising, since snowboarding is really great. The bad thing is that in order to gain speed, the area must slide downwards. Another disadvantage is that when you've reached the bottom of the hill you have to walk up again or wait for the ski-lift.
Michael would like to know how long the longest run in an area is. That area is given by a grid of numbers, defining the heights at those points. Look at this example:
 1  2  3  4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
One can slide down from one point to a connected other one if and only if the height decreases. One point is connected to another if it's at left, at right, above or below it. In the sample map, a possible slide would be 24-17-16-1 (start at 24, end at1). Of course if you would go 25-24-23-...-3-2-1, it would be a much longer run. In fact, it's the longest possible.
Input
The first line contains the number of test cases N. Each test case starts with a line containing the name (it's a single string), the number of rows R and the number of columns C. After that follow R lines with C numbers each, defining the heights.R and C won't be bigger than 100, N not bigger than 15 and the heights are always in the range from 0 to 100.
For each test case, print a line containing the name of the area, a colon, a space and the length of the longest run one can slide down in that area.
Sample Input
2
Feldberg 10 5
56 14 51 58 88
26 94 24 39 41
24 16 8 51 51
76 72 77 43 10
38 50 59 84 81
5 23 37 71 77
96 10 93 53 82
94 15 96 69 9
74 0 62 38 96
37 54 55 82 38
Spiral 5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9

Sample Output
Feldberg: 7
Spiral: 25

(Math Lovers’ Contest, Problem Setter: Stefan Pochmann)

DFS + backtracking

#include<stdio.h>
#include<cstring>
#include<string>
#include<vector>
#define REP(i, b, n) for (int i = b; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define DBG 0
using namespace std;

//bool trav[10000];
int LM,R,C;
int maz[100][100],num[100][100],dir[4][2];
bool trav[100][100];
void init(){
    dir[0][0]=-1,dir[1][1]=-1,dir[2][0]=1,dir[3][1]=1;
}
bool isValid(int a,int b){return a>=0&&a<R&&b>=0&&b<C;}
void DFS(int r,int c,int len){
    trav[r][c]=1;
    if(len>LM)LM=len;
    if(len>num[r][c])num[r][c]=len;
    int a,b;
    rep(i,4){
        a=r+dir[i][0],b=c+dir[i][1];
        if(isValid(a,b)&&maz[a][b]<maz[r][c]&&!trav[a][b]&&len+1>num[a][b]){
            DFS(a,b,len+1);
        }
    }
    trav[r][c]=0;
}
void ans(){
    memset(num,0,sizeof(num)),LM=0;
    rep(i,R)rep(j,C){
        DFS(i,j,1);
    }
    printf("%d\n",LM);
}
int main(){
    int n;
    char name[1000];
    init();
    scanf("%d",&n);
    rep(i,n){
        scanf("%s%d%d",name,&R,&C);
        rep(i,R)rep(j,C)scanf("%d",&maz[i][j]);
        printf("%s: ",name);
        ans();
    }
}

uva 10276 - Hanoi Tower Troubles Again!

Problem H
Hanoi Tower Troubles Again!
Input: Standard Input
Output: Standard Output
People stopped moving discs from peg to peg after they know the number of steps needed to complete the entire task. But on the other hand, they didn't not stopped thinking about similar puzzles with the Hanoi Tower. Mr.S invented a little game on it. The game consists of N pegs and a LOT of balls. The balls are numbered 1,2,3... The balls look ordinary, but they are actually magic. If the sum of the numbers on two balls is NOT a square number, they will push each other with a great force when they're too closed, so they can NEVER be put together touching each other.

The player should place one ball on the top of a peg at a time. He should first try ball 1, then ball 2, then ball 3... If he fails to do so, the game ends. Help the player to place as many balls as possible. You may take a look at the picture above, since it shows us a best result for 4 pegs.
Input
The first line of the input contains a single integer T, indicating the number of test cases. (1<=T<=50) Each test case contains a single integer N(1<=N<=50), indicating the number of pegs available.
Output
For each test case in the input print a line containing an integer indicating the maximal number of balls that can be placed. Print -1 if an infinite number of balls can be placed.
Sample Input
2
4
25
Sample Output
11
337
__________________________________________________________________________________________
Rujia Liu


DFS, O(1) solution exists here 

#include<stdio.h>
#include<cstring>
#include<cmath>
#include<string>
#include<vector>
#define REP(i, b, n) for (int i = b; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define DBG 0
using namespace std;

//bool trav[10000];
int LM,N;
int top[50];
bool isSqr(int c){
int a=int(sqrt(c));
return a*a==c;
}
void DFS(int cur,int len){
if(cur-1>LM)LM=cur-1;
int b;
rep(i,min(len+1,N)){
if(cur>LM-N&&(isSqr(top[i]+cur)||top[i]==0)){
if(DBG)printf("LM-N top cur loc %d %d %d %d\n",LM-N, top[i],cur,i);
b=top[i],top[i]=cur;
DFS(cur+1,min(max(i+2,len),N));
top[i]=b;
}
}
}
void ans(){
LM=0;
DFS(1,1);
printf("%d\n",LM);
}
int main(){
int n;
scanf("%d",&n);
rep(i,n)scanf("%d",&N),ans();
}

2012年9月19日 星期三

uva 539 - The Settlers of Catan



  The Settlers of Catan 

Within Settlers of Catan, the 1995 German game of the year, players attempt to dominate an island by building roads, settlements and cities across its uncharted wilderness.
You are employed by a software company that just has decided to develop a computer version of this game, and you are chosen to implement one of the game's special rules:


When the game ends, the player who built the longest road gains two extra victory points.


The problem here is that the players usually build complex road networks and not just one linear path. Therefore, determining the longest road is not trivial (although human players usually see it immediately).


Compared to the original game, we will solve a simplified problem here: You are given a set of nodes (cities) and a set of edges (road segments) of length 1 connecting the nodes. The longest road is defined as the longest path within the network that doesn't use an edge twice. Nodes may be visited more than once, though.


Example: The following network contains a road of length 12.

o        o -- o        o
 \      /      \      /
  o -- o        o -- o
 /      \      /      \
o        o -- o        o -- o
               \      /
                o -- o

Input 

The input file will contain one or more test cases.The first line of each test case contains two integers: the number of nodes n ( $2 \le n \le 25$) and the number of edges m ($1 \le m \le 25$). The next m lines describe the m edges. Each edge is given by the numbers of the two nodes connected by it. Nodes are numbered from 0 to n-1. Edges are undirected. Nodes have degrees of three or less. The network is not neccessarily connected.
Input will be terminated by two values of 0 for n and m.

Output 

For each test case, print the length of the longest road on a single line.

Sample Input 


3 2
0 1
1 2
15 16
0 2
1 2
2 3
3 4
3 5
4 6
5 7
6 8
7 8
7 9
8 10
9 11
10 12
11 12
10 13
12 14
0 0

Sample Output 


2
12



Miguel A. Revilla
1999-01-11

DFS
#include<stdio.h>
#include<cstring>
#include<cmath>
#include<string>
#include<ctime>
#include<vector>
#define REP(i, b, n) for (int i = b; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define DBG 0
using namespace std;

int N,LM;
int deg[25];
bool trav[25][25];
vector<int>edge[25];
bool DFS(int cur,int len){
    if(!deg[cur])LM=max(len,LM);
    else{
        int b;
        rep(i,edge[cur].size()){
            b=edge[cur][i];
            if(!trav[cur][b]){
                trav[cur][b]=trav[b][cur]=1,deg[cur]--,deg[b]--;
                DFS(b,len+1);
                trav[cur][b]=trav[b][cur]=0,deg[cur]++,deg[b]++;
            }
        }
    }
}
void ans(){
    LM=0;
    rep(i,N)deg[i]=edge[i].size();
    rep(i,N)DFS(i,0);
    printf("%d\n",LM);
}
int main(){
    int a,b,M;
    while(scanf("%d%d",&N,&M)==2){
        if(N==0&&M==0)break;
        rep(i,25)edge[i].clear();
        rep(i,M)scanf("%d%d",&a,&b),edge[a].push_back(b),edge[b].push_back(a);
        ans();
    }
}

uva 524 - Prime Ring Problem



  Prime Ring Problem 

A ring is composed of n (even number) circles as shown in diagram. Put natural numbers $1, 2, \dots, n$ into each circle separately, and the sum of numbers in two adjacent circles should be a prime.



Note: the number of first circle should always be 1.

Input 

n (0 < n <= 16)

Output 

The output format is shown as sample below. Each row represents a series of circle numbers in the ring beginning from 1 clockwisely and anticlockwisely. The order of numbers must satisfy the above requirements.

You are to write a program that completes above process.

Sample Input 

6
8

Sample Output 

Case 1:
1 4 3 2 5 6
1 6 5 2 3 4

Case 2:
1 2 3 8 5 6 7 4
1 2 5 8 3 4 7 6
1 4 7 6 5 8 3 2
1 6 7 4 3 8 5 2



Miguel A. Revilla
1999-01-11

DFS
#include<stdio.h>
#include<cstring>
#include<string>
#include<vector>
#define REP(i, b, n) for (int i = b; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define DBG 0
using namespace std;

int cases=1,N;
vector<int>res;
bool notp[50];
bool trav[16];
void getP(){
notp[0]=notp[1]=1;
REP(i,2,50){
if(!notp[i]){
if(DBG)printf("p %d\n",i);
for(int j=i*i;j<50;j+=i)notp[j]=1;
}
}
}
void print(){
bool ll=0;
rep(i,res.size()){if(ll)printf(" ");ll=1,printf("%d",res[i]);}printf("\n");
}
void DFS(int cur,int len){
if(DBG)printf("len %d\n",len);
if(len==N){if(DBG)printf("len %d: cur first %d %d\n",len,cur+1,res[0]);
if(!notp[cur+1+res[0]])print();}
else{
trav[cur]=1;
rep(i,N)
if(!trav[i]&&!notp[cur+1+(i+1)]){
if(DBG)printf("%d + %d is prime\n",cur+1,i+1);
res.push_back(i+1);
DFS(i,len+1);
res.pop_back();
}
trav[cur]=0;
}
}
void ans(){
res.clear(),res.push_back(1);
printf("Case %d:\n",cases++);
DFS(0,1);
}
int main(){
bool ll=0;
getP();
while(scanf("%d",&N)==1){
if(ll)printf("\n");ll=1;
ans();
}
}

2012年9月18日 星期二

uva 422 - Word-Search Wonder



 Word-Search Wonder 

The Pyrates Restaurant was starting to fill up as Valentine McKee walked in. She scanned the crowd for her sister, brother-in-law, and nephew. Seeing her sister waving from the far end of the restaurant, she made her way back to their booth. ``Hi, Valentine,'' her sister and brother-in-law, Niki and Dennis Chapman, greeted her.
``Hi, guys,'' she replied. ``What are you doing, Wade?'' she asked her nephew. He was busy working on one of the restaurant's activity sheets with a crayon.
``I'm doing a word search game,'' Wade explained. ``I have to find all of these words in this big mess of letters. This is really hard.'' Wade looked intently at the paper in front of him.
``Can I help?'' asked Valentine, looking across the table at the activity sheet.
``Sure. These are the words we're looking for. They're the names of different kinds of Planes, Trains, and Automobiles.''

Input

The first line of input will specify the length (in characters) of the sides of the letter matrix (the matrix of letters will be square). The length, l, will be in the range tex2html_wrap_inline28 . The next l lines of input will be the matrix itself, each line will contain l uppercase letters.
A list of words will follow. Each word will be on a line by itself; there will be 100 or fewer words. Each word will be 100 or fewer characters long, and will only contain uppercase letters.
The final line of input will contain a single zero character.

Output

Your program should attempt to find each word from the word list in the puzzle. A word is ``found'' if all the characters in the word can be traced in a single (unidirectional) horizontal, vertical, or diagonal line in the letter matrix. Words may not ``wrap around'' rows or columns, but horizontal and diagonal words may proceed from right to left (``backwards''). For each word that is found, your program should print the coordinates of its first and last letters in the matrix on a single line, separated by a single space. Coordinates are pairs of comma-separated integers (indexed from 1), where the first integer specifies the row number and the second integer specifies the column number.
If a word is not found, the string ``Not found'' should be output instead of a pair of coordinates.
Each word from the input can be ``found'' at most once in the puzzle.

Sample Input


5
EDEEE
DISKE
ESEEE
ECEEE
EEEEE
DISC
DISK
DISP
0

Sample Output


1,2 4,2
2,1 2,4
Not found

DFS

#include<stdio.h>
#include<cstring>
#include<string>
#include<vector>
#define REP(i, b, n) for (int i = b; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define DBG 0
using namespace std;

int cases=1,L,D;
vector<int>seq;
string T;
int comp[8][2],next[8],res[8],SR,SC,ER,EC;
vector<string>query;
char maz[110][110],dir[8][2];
vector<pair<int,int> >loc[26];
void init(){
dir[0][0]=-1,dir[1][1]=-1,dir[2][0]=1,dir[3][1]=1,
dir[4][0]=-1,dir[4][1]=-1,dir[5][0]=1,dir[5][1]=-1,
dir[6][0]=1,dir[6][1]=1,dir[7][0]=-1,dir[7][1]=1;
}
void getA(){
rep(i,L)rep(j,L)loc[maz[i][j]-'A'].push_back(make_pair(i,j));
}
bool isValid(int a,int b){return a>=0&&a<L&&b>=0&b<L;}
bool DFS(int r,int c,int len){
int a,b;
if(len==T.size()){ER=r,EC=c;return 1;}
else{
a=r+dir[D][0],b=c+dir[D][1];
if(isValid(a,b)&&maz[a][b]==T[len])
if(DFS(a,b,len+1))return 1;
return 0;
}
}
void ans(){
bool ok;
getA();
rep(i,query.size()){
ok=0;
rep(j,loc[query[i][0]-'A'].size()){
SR=loc[query[i][0]-'A'][j].first,SC=loc[query[i][0]-'A'][j].second;
if(DBG)printf("query %s: %d %d\n",query[i].c_str(),SR,SC);
rep(k,8){D=k,T=query[i];
if(DFS(SR,SC,1)){printf("%d,%d %d,%d\n",SR+1,SC+1,ER+1,EC+1),ok=1;break;}
}
}
if(!ok)printf("Not found\n");
}
}
int main(){
char chs[110];
scanf("%d",&L);
init();
rep(i,L)scanf("%s",maz[i]);
while(scanf("%s",chs)==1){
if(chs[0]=='0')break;
else query.push_back(chs);
}
ans();
}

2012年8月13日 星期一

uva 750 - 8 Queens Chess Problem



  8 Queens Chess Problem 

In chess it is possible to place eight queens on the board so that no one queen can be taken by any other. Write a program that will determine all such possible arrangements for eight queens given the initial position of one of the queens.
Do not attempt to write a program which evaluates every possible 8 configuration of 8 queens placed on the board. This would require 88 evaluations and would bring the system to its knees. There will be a reasonable run time constraint placed on your program.

Input 

The first line of the input contains the number of datasets, and it's followed by a blank line. Each dataset will be two numbers separated by a blank. The numbers represent the square on which one of the eight queens must be positioned. A valid square will be represented; it will not be necessary to validate the input.To standardize our notation, assume that the upper left-most corner of the board is position (1,1). Rows run horizontally and the top row is row 1. Columns are vertical and column 1 is the left-most column. Any reference to a square is by row then column; thus square (4,6) means row 4, column 6.
Each dataset is separated by a blank line.


Output 

Output for each dataset will consist of a one-line-per-solution representation.Each solution will be sequentially numbered $1 \dots N$. Each solution will consist of 8 numbers. Each of the 8 numbers will be the ROW coordinate for that solution. The column coordinate will be indicated by the order in which the 8 numbers are printed. That is, the first number represents the ROW in which the queen is positioned in column 1; the second number represents the ROW in which the queen is positioned in column 2, and so on.
The sample input below produces 4 solutions. The full 8$\times$8 representation of each solution is shown below.

DO NOT SUBMIT THE BOARD MATRICES AS PART OF YOUR SOLUTION!

   SOLUTION 1           SOLUTION 2           SOLUTION 3           SOLUTION 4

1 0 0 0 0 0 0 0      1 0 0 0 0 0 0 0      1 0 0 0 0 0 0 0      1 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0      0 0 0 0 0 0 1 0      0 0 0 0 0 1 0 0      0 0 0 0 1 0 0 0
0 0 0 0 1 0 0 0      0 0 0 1 0 0 0 0      0 0 0 0 0 0 0 1      0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 1      0 0 0 0 0 1 0 0      0 0 1 0 0 0 0 0      0 0 0 0 0 1 0 0
0 1 0 0 0 0 0 0      0 0 0 0 0 0 0 1      0 0 0 0 0 0 1 0      0 0 1 0 0 0 0 0
0 0 0 1 0 0 0 0      0 1 0 0 0 0 0 0      0 0 0 1 0 0 0 0      0 0 0 0 0 0 1 0
0 0 0 0 0 1 0 0      0 0 0 0 1 0 0 0      0 1 0 0 0 0 0 0      0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0      0 0 1 0 0 0 0 0      0 0 0 0 1 0 0 0      0 0 0 1 0 0 0 0
Submit only the one-line, 8 digit representation of each solution as described earlier. Solution #1 below indicates that there is a queen at Row 1, Column 1; Row 5, Column 2; Row 8, Column 3; Row 6, Column 4; Row 3,Column 5; ... Row 4, Column 8.
Include the two lines of column headings as shown below in the sample output and print the solutions in lexicographical order.
Print a blank line between datasets.

Sample Input 


1

1 1

Sample Output 


SOLN       COLUMN
 #      1 2 3 4 5 6 7 8

 1      1 5 8 6 3 7 2 4
 2      1 6 8 3 7 4 2 5
 3      1 7 4 6 8 2 5 3
 4      1 7 5 8 2 4 6 3



Miguel A. Revilla
2000-02-09

DFS

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<vector>
#include<queue>
#include<math.h>
#include<algorithm>
#define REP(i, b, n) for (int i = b; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define DBG 0

using namespace std;

int R,C;
bool thr[8][8];
int pad[4][2];
vector<vector<int> >res;
vector<int>cur;
void init(){
    pad[0][0]=-1,pad[0][1]=-1,
    pad[1][0]=-1,pad[1][1]=1,
    pad[2][0]=1,pad[2][1]=1,
    pad[3][0]=1,pad[3][1]=-1;
}
bool valid(int a,int b){
    return a>=0&&b>=0&&a<8&&b<8;
}
void add(int a,int b){
    rep(i,8)thr[a][i]=1,thr[i][b]=1;
    int c,d;
    rep(i,4){
        c=a,d=b;
        while(valid(c+pad[i][0],d+pad[i][1]))c+=pad[i][0],d+=pad[i][1],thr[c][d]=1;
    }
}
void DFS(int c){
    if(c==8){res.push_back(cur);return;}
    if(c==C){cur.push_back(R),DFS(c+1),cur.erase(cur.end()-1);}
    else{
        bool tthr[8][8];
        rep(i,8){
            if(!thr[i][c]){
                memcpy(tthr,thr,sizeof(thr));
                cur.push_back(i);
                if(DBG)printf("push %d %d\n",i,c);
                add(i,c);
                DFS(c+1);
                memcpy(thr,tthr,sizeof(thr));
                cur.erase(cur.end()-1);
            }
        }
    }
}
void getNum(){
    res.clear();
    if(DBG)rep(i,8){rep(j,8)printf("%d ",thr[i][j]);printf("\n");}
    DFS(0);
    rep(i,res.size()){
        printf("%2d      ",i+1);
        rep(j,res[i].size()){if(j)printf(" ");printf("%d",res[i][j]+1);}
        printf("\n");
    }
}
int main(){
    int a;
    bool ll=0;
    cin>>a;
    init();
    
    rep(i,a){
        memset(thr,0,sizeof(thr));
        cin>>R>>C,R--,C--;
        add(R,C);
        if(ll)printf("\n");ll=1;
        printf("SOLN       COLUMN\n #      1 2 3 4 5 6 7 8\n\n");
        getNum();
    }
}

2012年7月30日 星期一

uva 10000 - Longest Paths



  Longest Paths 

It is a well known fact that some people do not have their social abilities completely enabled. One example is the lack of talent for calculating distances and intervals of time. This causes some people to always choose the longest way to go from one place to another, with the consequence that they are late to whatever appointments they have, including weddings and programming contests. This can be highly annoying for their friends.
César has this kind of problem. When he has to go from one point to another he realizes that he has to visit many people, and thus always chooses the longest path. One of César's friends, Felipe, has understood the nature of the problem. Felipe thinks that with the help of a computer he might be able to calculate the time that César is going to need to arrive to his destination. That way he could spend his time in something more enjoyable than waiting for César.


Your goal is to help Felipe developing a program that computes the length of the longest path that can be constructed in a given graph from a given starting point (César's residence). You can assume that the graph has no cycles (there is no path from any node to itself), so César will reach his destination in a finite time. In the same line of reasoning, nodes are not considered directly connected to themselves.

Input 

The input consists of a number of cases. The first line on each case contains a positive number n ($1 < n \le 100$) that specifies the number of points that César might visit (i.e., the number of nodes in the graph).A value of n = 0 indicates the end of the input.


After this, a second number s is provided, indicating the starting point in César's journey ( $1 \le s \le n$). Then, you are given a list of pairs of places p and q, one pair per line, with the places on each line separated by white-space. The pair ``$p \ q$" indicates that César can visit q after p.
A pair of zeros (``0 0") indicates the end of the case.


As mentioned before, you can assume that the graphs provided will not be cyclic.

Output 

For each test case you have to find the length of the longest path that begins at the starting place. You also have to print the number of the final place of such longest path. If there are several paths of maximum length, print the final place with smallest number.

Print a new line after each test case.

Sample Input 

2
1
1 2
0 0
5
3
1 2
3 5
3 1
2 4
4 5
0 0
5
5
5 1
5 2
5 3
5 4
4 1
4 2
0 0
0

Sample Output 

Case 1: The longest path from 1 has length 1, finishing at 2.

Case 2: The longest path from 3 has length 4, finishing at 5.

Case 3: The longest path from 5 has length 2, finishing at 1.



Miguel Revilla
2000-08-21

DFS