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();
}

uva 216 - Getting in Line



 Getting in Line 

Computer networking requires that the computers in the network be linked.

This problem considers a ``linear" network in which the computers are chained together so that each is connected to exactly two others except for the two computers on the ends of the chain which are connected to only one other computer. A picture is shown below. Here the computers are the black dots and their locations in the network are identified by planar coordinates (relative to a coordinate system not shown in the picture).
Distances between linked computers in the network are shown in feet.

For various reasons it is desirable to minimize the length of cable used.

Your problem is to determine how the computers should be connected into such a chain to minimize the total amount of cable needed. In the installation being constructed, the cabling will run beneath the floor, so the amount of cable used to join 2 adjacent computers on the network will be equal to the distance between the computers plus 16 additional feet of cable to connect from the floor to the computers and provide some slack for ease of installation.

The picture below shows the optimal way of connecting the computers shown above, and the total length of cable required for this configuration is (4+16)+ (5+16) + (5.83+16) + (11.18+16) = 90.01 feet.

Input

The input file will consist of a series of data sets. Each data set will begin with a line consisting of a single number indicating the number of computers in a network. Each network has at least 2 and at most 8 computers. A value of 0 for the number of computers indicates the end of input.
After the initial line in a data set specifying the number of computers in a network, each additional line in the data set will give the coordinates of a computer in the network. These coordinates will be integers in the range 0 to 150. No two computers are at identical locations and each computer will be listed once.

Output

The output for each network should include a line which tells the number of the network (as determined by its position in the input data), and one line for each length of cable to be cut to connect each adjacent pair of computers in the network. The final line should be a sentence indicating the total amount of cable used.

In listing the lengths of cable to be cut, traverse the network from one end to the other. (It makes no difference at which end you start.) Use a format similar to the one shown in the sample output, with a line of asterisks separating output for different networks and with distances in feet printed to 2 decimal places.

Sample Input


6
5 19
55 28
38 101
28 62
111 84
43 116
5
11 27
84 99
142 81
88 30
95 38
3
132 73
49 86
72 111
0

Sample Output


**********************************************************
Network #1
Cable requirement to connect (5,19) to (55,28) is 66.80 feet.
Cable requirement to connect (55,28) to (28,62) is 59.42 feet.
Cable requirement to connect (28,62) to (38,101) is 56.26 feet.
Cable requirement to connect (38,101) to (43,116) is 31.81 feet.
Cable requirement to connect (43,116) to (111,84) is 91.15 feet.
Number of feet of cable required is 305.45.
**********************************************************
Network #2
Cable requirement to connect (11,27) to (88,30) is 93.06 feet.
Cable requirement to connect (88,30) to (95,38) is 26.63 feet.
Cable requirement to connect (95,38) to (84,99) is 77.98 feet.
Cable requirement to connect (84,99) to (142,81) is 76.73 feet.
Number of feet of cable required is 274.40.
**********************************************************
Network #3
Cable requirement to connect (132,73) to (72,111) is 87.02 feet.
Cable requirement to connect (72,111) to (49,86) is 49.97 feet.
Number of feet of cable required is 136.99.

backtracking
#include<stdio.h>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<string>
#include<vector>
#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;

int cases=1,N,start,end;
vector<int>seq;
int comp[8][2],next[8],res[8];
bool trav[8];
float dis[8][8],mx,sum;
void getDis(){
rep(i,N)REP(j,i+1,N)
dis[i][j]=dis[j][i]=sqrt(pow(fabs(comp[i][0]-comp[j][0]),2)+pow(fabs(comp[i][1]-comp[j][1]),2));
}
void DFS(int root,int cur,int cnt){
if(DBG)printf("DFS %d %d %d: %f\n",root,cur,cnt,sum);
if(cnt==N){if(sum<mx)end=cur,start=root,mx=sum,memcpy(res,next,sizeof(next));}

else{
trav[cur]=1;
rep(i,N){
if(i!=cur&&!trav[i]){
next[cur]=i;
if(sum+dis[cur][i]>mx)continue;
sum+=dis[cur][i];
DFS(root,i,cnt+1);
sum-=dis[cur][i];
}
}
trav[cur]=0;
}
}
void ans(){
getDis();
mx=1e9,memset(trav,0,sizeof(trav)),start=end=-1;
rep(i,N){
sum=0;
if(i!=start)DFS(i,i,1); //pick one start
}
int c=start,cnt=0;
sum=0;
while(cnt<N-1){
printf("Cable requirement to connect (%d,%d) to (%d,%d) is %.2f feet.\n",
comp[c][0],comp[c][1],comp[res[c]][0],comp[res[c]][1],dis[c][res[c]]+16);
sum+=dis[c][res[c]]+16;
c=res[c];
cnt++;
}
printf("Number of feet of cable required is %.2f.\n",sum);
}
int main(){
while(scanf("%d",&N)==1){
if(N==0)break;
rep(i,N)scanf("%d%d",&comp[i][0],&comp[i][1]);
printf("**********************************************************\n");
printf("Network #%d\n",cases++);
ans();
}

}

2012年9月14日 星期五

uva 391 - Makr-up



 Mark-up 

Mark-up languages are computer languages that assist in the formatting of text files. Special keywords are used to mark the text to allow control of fonts, page styles, paragraph styles, etc. TeX, troff, and HTML are examples of mark-up languages.

Spell checking can be difficult to adapt to these special texts. In general, special processors or spell checkers must be created in order to accommodate mark-up languages. A special processor would recognize the mark-up language and strip it from the text so that the ``plain'' text could then be processed by a spell checker. For this problem, you are to write such a processor for a small mark-up language so that the output of your program will be the plain text without the mark-ups.

The mark-up language to consider is one which allows the modification of fonts within the text. Each markup command will be preceded by a \ character. If the letter following the \ character is not a recognized command from the table below then the character following the \ is printed as part of the plain text. For instance, the mark-up \\ can be used to print a single \.

tex2html_wrap_inline31 b
toggle bold font on/off (default state is off)
tex2html_wrap_inline31 i
toggle italics font on/off (default state is off)
tex2html_wrap_inline31 s
set font size; the s is immediately followed by an optional number; if the number is missing then the command will restore the previous size
tex2html_wrap_inline31 *
toggle processing of mark-ups on/off; if processing is toggled off then mark-ups are considered to be literal text (default state is on)
The number following the SPMamp& command can have a decimal point so 12, 9.5, 11., and .5 should all be recognized as valid numbers.

Input and Output

The input file will be plain text containing mark-ups from the language above. At the start, processing of mark-ups should be on. The file should be processed until the end-of-file is encountered.

Sample Input


\s18.\bMARKUP sample\b\s

\*For bold statements use the \b command.\*

If you wish to \iemphasize\i something use the \\i command.

For titles use \s14BIG\s font sizes, 14 points usually works well.

Remember that all of the commands toggle except for the \\s command.

Sample Output


MARKUP sample

For bold statements use the \b command.

If you wish to emphasize something use the \i command.

For titles use BIG font sizes, 14 points usually works well.

Remember that all of the commands toggle except for the \s command.

output

#include<stdio.h>
#include<cstring>
#include<string>
#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 markup;
string cmd;
string getCmd(int &cur){
if(DBG)printf("getcmd %d\n",cur);
if(cmd[cur]=='\\'){
if(!markup)
if(cur+1>=cmd.size()||cmd[cur+1]!='*'){cur+=1;return "\\";} //go one letter
else{markup=1,cur+=2;return "";}
if(cmd[cur+1]=='\\'){cur+=2;return "\\";}
else if(cmd[cur+1]=='b'||cmd[cur+1]=='i'){cur+=2;}
else if(cmd[cur+1]=='*'){cur+=2,markup=!markup;}
else if(cmd[cur+1]=='s'){
int c=cur+2;
bool pp=0;
while(c<cmd.size()&&isdigit(cmd[c]))c++;
if(c<cmd.size()&&cmd[c]=='.')pp=1,c++;
while(c<cmd.size()&&isdigit(cmd[c]))c++;
if(DBG)printf("get num %s\n",cmd.substr(cur+2,c-cur-2).c_str());
if(c-cur==3&&pp)cur+=2; //only .
else cur+=c-cur;
}
else cur++; //useless
return "";
}
else{
int c=cur;
while(cur<cmd.size()&&cmd[cur]!='\\')cur++;
return cmd.substr(c,cur-c);
}
}
void ans(){
int cur=0;
string next,res;
while(1){
if(cur>=cmd.size())break;
next=getCmd(cur);
if(DBG)printf("next: %s\n",next.c_str());
res+=next;
}
printf("%s\n",res.c_str());
}
int main(){
char chs[1024];
markup=1;
while(fgets(chs,1024,stdin)){
if(chs[0]=='\n'){printf("\n");continue;}
if(chs[strlen(chs)-1]=='\n')chs[strlen(chs)-1]='\0';
cmd=chs;
ans();
}
}

uva 337 - 337 - Interpreting Control Sequences



 Interpreting Control Sequences 

Virtually all text-mode terminals are special-purpose computer systems, including a serial port (for communication with a modem or another computer system), a keyboard, a CRT, and of course, a microprocessor, some RAM, and a control program in ROM.
When a character arrives at the terminal, either from the keyboard or the serial port, the terminal's software classifies it as either a display character (which is to be displayed on the CRT) or as a character that introduces a control sequence. A control sequence is used to direct the terminal to do such things as clear the screen, move the cursor in a specified manner, or perhaps change fonts.
In this problem assume you are writing the software for a small terminal with a 10-row, 10-column display (perhaps for a point-of-sale terminal). Rows and columns are numbered 0 through 9. The character that introduces a control sequence is tex2html_wrap_inline39, the circumflex. The character (or in one case, the two characters) immediately following the control sequence introducer will direct your software in performing its special functions. Here is the complete list of control sequences you will need to interpret:

tex2html_wrap_inline39 b
Move the cursor to the beginning of the current line; the cursor row does not change
tex2html_wrap_inline39 c
Clear the entire screen; the cursor row and column do not change
tex2html_wrap_inline39 d
Move the cursor down one row if possible; the cursor column does not change
tex2html_wrap_inline39 e
Erase characters to the right of, and including, the cursor column on the cursor's row; the cursor row and column do not change
tex2html_wrap_inline39 h
Move the cursor to row 0, column 0; the image on the screen is not changed
tex2html_wrap_inline39 i
Enter insert mode (see below)
tex2html_wrap_inline39 l
Move the cursor left one column, if possible; the cursor row does not change
tex2html_wrap_inline39 o
Enter overwrite mode (see below)
tex2html_wrap_inline39 r
Move the cursor right one column, if possible; the cursor row does not change
tex2html_wrap_inline39 u
Move the cursor up one row, if possible; the cursor column does not change
tex2html_wrap_inline61
Write a circumflex ( tex2html_wrap_inline39 ) at the current cursor location, exactly as if it was not a special character; this is subject to the actions of the current mode (insert or overwrite)
tex2html_wrap_inline39 ##
Move the cursor to the row and column specified; # represents a decimal digit; the first # represents the new row number, and the second # represents the new column number
No illegal control sequences will ever be sent to the terminal. The cursor cannot move outside the allowed screen locations (that is, between row 0, column 0 and row 9, column 9).

When a normal character (not part of a control sequence) arrives at the terminal, it is displayed on the terminal screen in a manner that depends on the terminal mode. When the terminal is in overwrite mode (as it is when it is first turned on), the received character replaces the character at the cursor's location. But when the terminal is in insert mode, the characters to the right of and including the cursor's location are shifted right one column, and the new character is placed at the cursor's location; the character previously in the rightmost column of the cursor's row is lost. Regardless of the mode, the cursor is moved right one column, if possible.

Input

The input will contain multiple tests of your terminal software. Each test begins with a line containing an integer N. Following this line there will be N more lines of data, each character of which is to be treated as if it was input, in the order read, to your terminal software. There will be no tab characters in the input data, and ends of lines in the input are to be ignored. Note that blanks in the input data are normal characters to be displayed on your terminal's screen. The last test will be followed by a single line containing the integer 0. No control sequence will be split between two lines of the input data.

At the beginning of each test case you are to assume the terminal screen is clear (that is, filled with blanks), that the terminal is in overwrite mode, and that the cursor is in row 0, column 0 of the screen.

Output

For each input test case, output a line with the case number (these are numbered sequentially starting with 1) and the screen image the way it would look at the end of processing the data in the test case. Enclose the screen image in a "box;" see the sample below for illustration of the required format.

Sample Input


7
This is bad^h^c
^05^^
^14/ \^d^b   /   \
^u^d^d^l^l^l^l^l^l^l^l^l
^r^r< ACM >^l^l^d/^b   \
^b^d    \ /
^d^l^lv
7
^i9^l8^l7^l6^l5^l4^l3^l2^l1^l0
^o^d^lThis is #1^d^bThis is #2
^d^bThis is #3^d^bThis is #4
^d^bThis is #5^d^bThis is #6
^d^bThis is #7^d^bThis is #8
^i^d^bThis is #9^d^bThis is #10
^54^e Hello^d^l^l^l^lWorld
0

Sample Output


Case 1
+----------+
|     ^    |
|    / \   |
|   /   \  |
|  < ACM > |
|   \   /  |
|    \ /   |
|     v    |
|          |
|          |
|          |
+----------+
Case 2
+----------+
|0123456789|
|This is #1|
|This is #2|
|This is #3|
|This is #4|
|This Hello|
|This World|
|This is #7|
|This is #8|
|This is #0|
+----------+

output
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<string>
#include<map>
#include<sstream>
#include<iostream>
#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 CR,CC,dir[4][2],cases=1;
string screen[10];
bool mode;
char cd[128];
string cmd;
void init(){
    dir[0][0]=-1,dir[1][1]=1,dir[2][0]=1,dir[3][1]=-1;
    cd['u']=0,cd['r']=1,cd['d']=2,cd['l']=3;
}
string getCmd(int &cur,int &type){
    string cd;
    if(cmd[cur]=='^'){
        type=1;
        if(isdigit(cmd[cur+1])){cd=cmd.substr(cur,3),cur+=3;return cd;}
        else{cd=cmd.substr(cur,2),cur+=2;return cd;}
    }
    else{
        type=2;
        int c=cur;
        while(cur<cmd.size()&&cmd[cur]!='^')cur++;
        return cmd.substr(c,cur-c);
    }
}
void append(string a){
    if(!mode){
        screen[CR].insert(CC,a);
        if(screen[CR].size()>10)screen[CR]=screen[CR].substr(0,10);
    }
    else{
        REP(i,CC,CC+a.size()){
            if(i>=10)break;
            screen[CR][i]=a[i-CC];
        }
    }
    CC+=a.size();
    if(CC>10)screen[CR][9]=a[a.size()-1];
    if(CC>=10)CC=9;
}
bool isValid(int r,int c){return r>=0&&r<10&&c>=0&&c<10;}
void print(){rep(i,10){printf("+");rep(j,10)printf("%c",screen[i][j]);printf("+\n");}}
void go(){
    int cur=0,type;
    string next;
    while(1){
        next=getCmd(cur,type);
        if(DBG)printf("cmd %s(%d %d)\n",next.c_str(),CR,CC);
        if(DBG)print();
        if(type==1){
            if(next[1]=='h')CR=CC=0;
            else if(next[1]=='b')CC=0;
            else if(next[1]=='c')rep(i,10)screen[i].assign(10,' ');
            else if(next[1]=='d'||next[1]=='u'||next[1]=='l'||next[1]=='r'){
                if(isValid(CR+dir[cd[next[1]]][0],CC+dir[cd[next[1]]][1]))
                    CR+=dir[cd[next[1]]][0],CC+=dir[cd[next[1]]][1];
            }
            else if(next[1]=='e')REP(i,CR,10)screen[CR][i]=' ';
            else if(next[1]=='i')mode=0;
            else if(next[1]=='o')mode=1;
            else if(isdigit(next[1]))CR=next[1]-'0',CC=next[2]-'0';
            else if(next[1]=='^')append("^");
        }
        else append(next);                  //add text
        if(cur>=cmd.size())break;
    }
}
void ans(){
    printf("Case %d\n",cases++);
    printf("+----------+\n");
    rep(i,10){printf("|");printf("%s",screen[i].c_str());printf("|\n");}
    printf("+----------+\n");
}

int main(){
    int a;
    char chs[200];
    init();
    while(scanf("%d ",&a)==1){
        if(a==0)break;
        CR=0,CC=0,mode=1;
        rep(i,10)screen[i].assign(10,' ');
        rep(i,a){
            fgets(chs,200,stdin);
            if(chs[strlen(chs)-1]=='\n')chs[strlen(chs)-1]='\0';
            cmd=chs,go();
        }
        ans();
    }
    
}

2012年9月13日 星期四

uva 320 - Border



 Border 

You are to write a program that draws a border around a closed path into a bitmap, as displayed in the following figure:

The path is closed and runs along the grid lines, i.e. between the squares of the grid. The path runs counter-clockwise, so if following the path is considered as going ``forward'', the border pixels are always to the ``right'' of the path. The bitmap always covers 32 by 32 squares and has its lower left corner at (0,0). You can safely assume that the path never touches the bounding rectangle of the bitmap and never touches or crosses itself. Note that a bit gets set if it is on the outside of the area surrounded by the path and if at least one of its edges belongs to the path, but not if only one of its corners is in the path. (A look at the convex corners in the figure should clarify that statement.)

Input

The first line of the input file contains the number of test cases in the file. Each test case that follows consists of two lines. The first line of each case contains two integer numbers x and y specifying the starting point of the path. The second line contains a string of variable length. Every letter in the string symbolizes a move of length one along the grid. Only the letters`W' (``west''), `E' (``east''), `N' (``north''), `S' (``south''), and `.' (``end of path'', no move) appear in the string. The end-of-path character (`.') is immediately followed by the end of the line.

Output

For each test case, output a line with the number of the case (`Bitmap #1'`Bitmap #2', etc.). For each row of the bitmap from top to bottom, print a line where you print a character for every bit in that row from left to right. Print an uppercase`X' for set bits and a period `.' for unset bits. Output a blank line after each bitmap.

Sample Input


1
2 1
EENNWNENWWWSSSES.

Sample Output


Bitmap #1
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
.XXX............................
X...X...........................
X..X............................
X...X...........................
.X..X...........................
..XX............................

simulation
#include<stdio.h>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<iostream>
#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,R,C,pdir[4][2],dir[4][2],ctd[128];
bool occ[32][32];
vector<char>seq;
void init(){
    pdir[0][1]=-1,pdir[2][0]=-1,pdir[3][0]=-1,pdir[3][1]=-1;
    dir[0][0]=1,dir[1][1]=1,dir[2][0]=-1,dir[3][1]=-1;
    ctd['E']=0,ctd['N']=1,ctd['W']=2,ctd['S']=3;
}
bool isValid(int r,int c){return r>=0&&r<32&&c>=0&&c<32;}
void ans(){
    int x,y,cr=R,cc=C;
    memset(occ,0,sizeof(occ));
    rep(i,seq.size()){
        x=cr+pdir[ctd[seq[i]]][0],y=cc+pdir[ctd[seq[i]]][1];
        if(DBG)printf("cr cc %d %d %d %d\n",cr,cc,x,y);
        if(isValid(x,y))occ[x][31-y]=1;
        cr+=dir[ctd[seq[i]]][0],cc+=dir[ctd[seq[i]]][1];
        if(cr==R&&cc==C)break;
    }
    printf("Bitmap #%d\n",cases++);
    rep(i,32){
        rep(j,32)if(occ[j][i])printf("X");else printf(".");
        printf("\n");
    }
    printf("\n");
}
int main(){
    int n;
    char a;
    init();
    scanf("%d",&n);
    rep(i,n){
        seq.clear();
        scanf("%d%d ",&R,&C);
        if(DBG)printf("R C %d %d\n",R,C);
        while(scanf("%c",&a)==1){
            if(a=='\n'){break;}
            seq.push_back(a);
        }
        ans();
    }
}

uva 312 - Crosswords (II)



 Crosswords (II) 

A crossword can be stored as a matrix tex2html_wrap_inline26 of zeros and ones. Zero represents white squares and one represents black squares. Some squares of the crossword are numbered and assigned to these numbers are the descriptions of the words that should be written either ``across'' or ``down'' into the crossword. A square is numbered if it is a white square and either (a) the square below it is white and there is no white square immediately above, or (b) there is no white square immediately to its left and the square to its right is white. The squares are numbered from left to right, from the top line to the bottom line.
From the matrix a crossword diagram can be drawn. In the diagram each square is represented by a box tex2html_wrap_inline28 characters. Black square and white squares (numbered and not numbered square) are represented as follows (where nnn is the number of the square):

++++++                        ++++++         ++++++
++++++                        +nnn +         +    +
++++++                        +    +         +    +
++++++                        ++++++         ++++++
The remaining characters of the box are spaces. If black squares are given at the edges, they should be removed from the diagram (see the example). Only use spaces as necessary filling characters. Don't use any unnecessary spaces at the end of the line.

Input

The input file consists of several blocks of lines each representing a crossword. Each block starts with the line containing two integers m < 25 and n < 25 separated by one space. In each of the next m lines there are n numbers 0 or 1, separated by one space. The last block will be empty, m = n = 0.

Output

The output file contains the corresponding crossword diagram for each except the last block. After each diagram there is one empty line.

Sample Input


6 7
1 0 0 0 0 1 1
0 0 1 0 0 0 0
0 0 0 0 1 0 0
0 1 0 0 1 1 1
0 0 0 1 0 0 0
1 0 0 0 0 0 1
5 3
1 0 1
0 0 0
1 1 1
0 0 0
1 0 1
0 0

Sample Output


     +++++++++++++++++++++
     +001 +    +002 +003 +
     +    +    +    +    +
++++++++++++++++++++++++++++++++++++
+004 +    ++++++005 +    +006 +007 +
+    +    ++++++    +    +    +    +
++++++++++++++++++++++++++++++++++++
+008 +    +009 +    +    +010 +    +
+    +    +    +    +    +    +    +
+++++++++++++++++++++    +++++++++++
+    ++++++011 +    +
+    ++++++    +    +
++++++++++++++++++++++++++++++++++++
+012 +013 +    ++++++014 +015 +    +
+    +    +    ++++++    +    +    +
++++++++++++++++++++++++++++++++++++
     +016 +    +    +    +    +
     +    +    +    +    +    +
     ++++++++++++++++++++++++++

     ++++++
     +001 +
     +    +
++++++++++++++++
+002 +    +    +
+    +    +    +
++++++++++++++++


++++++++++++++++
+003 +004 +    +
+    +    +    +
++++++++++++++++
     +    +
     +    +
     ++++++

flood-fill, output
#include<stdio.h>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<iostream>
#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,M,dir[4][2],num[25][25],maz[25][25];
bool notprint[25][25];
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<N&&b>=0&&b<M;}
bool isSpace(int a,int b){return isValid(a,b)&&maz[a][b]==0;}
bool isWall(int a,int b){return !isValid(a,b)||maz[a][b]==1;}
bool isOk(int r,int c){
return maz[r][c]==0&&
(isWall(r-1,c)&&isSpace(r+1,c)||isWall(r,c-1)&&isSpace(r,c+1));
}
string ita(int a){
string s;
while(a>0)s+=(a%10+'0'),a/=10;
while(s.size()<3)s+='0';
reverse(s.begin(),s.end());
return s;
}
bool isEdge(int i,int j){return isValid(i,j)&&i==0||j==0||i==N-1||j==M-1;}
void flood(int r,int c){
notprint[r][c]=1;
//if(DBG)printf("fld: %d %d\n",r,c);
int x,y;
rep(i,4){
x=r+dir[i][0],y=c+dir[i][1];
if(isValid(x,y)&&maz[x][y]==1&&!notprint[x][y])flood(x,y);
//else if(DBG)printf("notprint %d %d: %d\n",x,y,notprint[x][y]);
}
}
void print(int num[][25]){rep(i,N){rep(j,M)printf("%d ",num[i][j]);printf("\n");}}
void print(bool num[][25]){rep(i,N){rep(j,M)printf("%d ",num[i][j]);printf("\n");}}
string intersect(string a,string b){
//if(DBG)printf("inter\n%s\n%s\n",a.c_str(),b.c_str());
string s;
rep(i,max(a.size(),b.size()))
if(i<a.size()&&i<b.size())s+=((a[i]=='+'||b[i]=='+')?'+':' ');
else if(i<a.size())s+=a[i];
else s+=b[i];
//if(DBG)printf("res\n%s\n",s.c_str());
return s;
}
void revise(vector<string>&res){
int cur=3;
for(int cur=3;cur+1<res.size();cur+=4){
string s1=res[cur],s2=res[cur+1],s3;
s3=intersect(s1,s2);
res.erase(res.begin()+cur+1),res.erase(res.begin()+cur);
res.insert(res.begin()+cur,s3);
cur--;
}
}
void ans(){
int c=1,d;
int cnum[25];
memset(num,0,sizeof(num));
memset(cnum,-1,sizeof(cnum));
memset(notprint,0,sizeof(notprint));
rep(i,N)rep(j,M)if(isOk(i,j))num[i][j]=c++;
if(DBG){printf("num: \n");print(num);}
rep(i,N)rep(j,M)if(isEdge(i,j)&&maz[i][j]==1&&!notprint[i][j])flood(i,j);
if(DBG){printf("edge: \n");print(notprint);printf("\n");}
rep(i,N)rep(j,M)if(maz[i][j]==0)cnum[i]=j;
vector<string>res;
string s;
rep(i,N){
rep(k,4){
s="";
rep(j,M){
if(!notprint[i][j]){
if(k==0)s+="+++++";
if(k==1)
if(num[i][j])s+="+"+ita(num[i][j])+" ";
else if(maz[i][j]==0)s+="+ ";
else s+="+++++";
if(k==2)if(maz[i][j]==0)s+="+ "; else s+="+++++";
if(k==3)s+="+++++";
}
else if(j<=cnum[i]) //empty cell
if(s.size()&&(!notprint[i][j-1]))s+="+ "; //close
else s+=" ";
else break;
}
if(s.size())s+="+"; //last
if(DBG)printf("s %s\n",s.c_str());
res.push_back(s);
}
}
revise(res);
rep(i,res.size())printf("%s\n",res[i].c_str());
printf("\n");
}
int main(){
int n,c;
init();
while(cin>>N>>M){
if(N==0&&M==0)break;
rep(i,N)rep(j,M)scanf("%d",&maz[i][j]);
ans();
}
}

uva 758 - The Same Game



  The Same Game 

The game named ``Same'' is a single-person game played on a 10 $\times$ 15 board. Each square contains a ball colored red (R), green (G), or blue (B). Two balls belong to the same cluster if they have the same color, and one can be reached from another by following balls of the same color in the four directions up, down, left, and right. At each step of the game, the player chooses a ball whose cluster has at least two balls and removes all balls in the cluster from the board. Then, the board is ``compressed'' in two steps:

1.
Shift the remaining balls in each column down to fill the empty spaces. The order of the balls in each column is preserved.
2.
If a column becomes empty, shift the remaining columns to the left as far as possible. The order of the columns is preserved.


For example, choosing the ball at the bottom left corner in the sub-board below causes:

The objective of the game is to remove every ball from the board, and the game is over when every ball is removed or when every cluster has only one ball. The scoring of each game is as follows. The player starts with a score of 0. When a cluster of m balls is removed, the player's score increases by (m - 2)2. A bonus of 1000 is given if every ball is removed at the end of the game.


You suspect that a good strategy might be to choose the ball that gives the largest possible cluster at each step, and you want to test this strategy by writing a program to simulate games played using this strategy. If there are two or more balls to choose from, the program should choose the leftmost ball giving the largest cluster. If there is still a tie, it should choose the bottommost ball of these leftmost balls.

Input 

You will be given a number of games in the input. The first line of input contains a positive integer giving the number of games to follow. The initial arrangement of the balls of each game is given one row at a time, from top to bottom. Each row contains 15 characters, each of which is one of ``R'', ``G'', or ``B'', specifying the colors of the balls in the row from left to right. A blank line precedes each game.

Output 

For each game, print the game number, followed by a new line, followed by information about each move, followed by the final score. Each move should be printed in the format:

Move x at (r,c): removed b balls of color C, got s points.


where x is the move number, r and c are the row number and column number of the chosen ball, respectively. The rows are numbered from 1 to 10 from the bottom, and columns are numbered from 1 to 15 from the left. b is the number of balls in the cluster removed. C is one of ``R'', ``G'', or ``B'', indicating the color of the balls removed. s is the score for this move. The score does not include the 1000 point bonus if all the balls are removed after the move.


The final score should be reported as follows:


Final score: s, with b balls remaining.


Insert a blank line between the output of each game. Use the plural forms ``balls'' and ``points'' even if the corresponding value is 1.

Sample Input 

3

RGGBBGGRBRRGGBG
RBGRBGRBGRBGRBG
RRRRGBBBRGGRBBB
GGRGBGGBRRGGGBG
GBGGRRRRRBGGRRR
BBBBBBBBBBBBBBB
BBBBBBBBBBBBBBB
RRRRRRRRRRRRRRR
RRRRRRGGGGRRRRR
GGGGGGGGGGGGGGG

RRRRRRRRRRRRRRR
RRRRRRRRRRRRRRR
GGGGGGGGGGGGGGG
GGGGGGGGGGGGGGG
BBBBBBBBBBBBBBB
BBBBBBBBBBBBBBB
RRRRRRRRRRRRRRR
RRRRRRRRRRRRRRR
GGGGGGGGGGGGGGG
GGGGGGGGGGGGGGG

RBGRBGRBGRBGRBG
BGRBGRBGRBGRBGR
GRBGRBGRBGRBGRB
RBGRBGRBGRBGRBG
BGRBGRBGRBGRBGR
GRBGRBGRBGRBGRB
RBGRBGRBGRBGRBG
BGRBGRBGRBGRBGR
GRBGRBGRBGRBGRB
RBGRBGRBGRBGRBG

Sample Output 

Game 1:

Move 1 at (4,1): removed 32 balls of color B, got 900 points.
Move 2 at (2,1): removed 39 balls of color R, got 1369 points.
Move 3 at (1,1): removed 37 balls of color G, got 1225 points.
Move 4 at (3,4): removed 11 balls of color B, got 81 points.
Move 5 at (1,1): removed 8 balls of color R, got 36 points.
Move 6 at (2,1): removed 6 balls of color G, got 16 points.
Move 7 at (1,6): removed 6 balls of color B, got 16 points.
Move 8 at (1,2): removed 5 balls of color R, got 9 points.
Move 9 at (1,2): removed 5 balls of color G, got 9 points.
Final score: 3661, with 1 balls remaining.

Game 2:

Move 1 at (1,1): removed 30 balls of color G, got 784 points.
Move 2 at (1,1): removed 30 balls of color R, got 784 points.
Move 3 at (1,1): removed 30 balls of color B, got 784 points.
Move 4 at (1,1): removed 30 balls of color G, got 784 points.
Move 5 at (1,1): removed 30 balls of color R, got 784 points.
Final score: 4920, with 0 balls remaining.

Game 3:

Final score: 0, with 150 balls remaining.


Miguel A. Revilla
2000-02-09

simulation

#include<stdio.h>
#include<cstring>
#include<string>
#include<iostream>
#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=15,M=10,LEFT,cases=1,total,score,move;
bool erase[15][10],erase2[15][10];
char dir[4][2];
vector<string>vc;
void init(){
dir[0][0]=1,dir[1][0]=-1,dir[2][1]=1,dir[3][1]=-1;
}
bool isValid(int r,int c){return r>=0&&r<vc.size()&&c>=0&&c<vc[r].size();}
void flood(int r,int c,char tar){
int a,b;
if(erase[r][c])return;
if(DBG)printf("(flood) %d,%d %c\n",r,c,vc[r][c]);
total++;
erase[r][c]=erase2[r][c]=1;
rep(i,4){
a=r+dir[i][0],b=c+dir[i][1];
if(isValid(a,b)&&vc[a][b]==tar)
flood(a,b,tar);
}
}
void del(bool erase[][10]){
int b,c,i,rsize=vc.size();
rep(k,rsize){
i=rsize-1-k;
c=vc[i].size();
rep(j,c)
if(erase[i][c-1-j]){
//if(DBG)printf("erase %d %d\n",i,c-1-j);
vc[i].erase(vc[i].begin()+c-1-j);
if(!vc[i].size())vc.erase(vc.begin()+i);;
}
}
}
void print(){
int c;
rep(i,M){
c=M-i;
rep(j,vc.size()){
if(j>0)printf(" ");else printf(" ");
if(vc[j].size()>=c)printf("%c",vc[j][c-1]);
else printf(" ");
}
printf("\n");
}
}
bool go(){
bool er[15][10];
memset(erase,0,sizeof(erase));
total=0;
int m=0,mr,mc;
rep(i,15)rep(j,10){
if(vc.size()>i&&vc[i].size()>j
&&!erase[i][j]){
memset(erase2,0,sizeof(erase2));
if(DBG){printf("flood %d,%d %c\n",i,j,vc[i][j]);}
total=0;
flood(i,j,vc[i][j]);
if(DBG)printf("rt\n");
if(DBG)printf("totol %d\n",total);
if(total>1&&m<total)memcpy(er,erase2,sizeof(er)),m=total,mr=i,mc=j;
}
}
if(m>1){
int sc=(m-2)*(m-2);
printf("Move %d at (%d,%d): removed %d balls of color %c, got %d points.\n",
move++,mc+1,mr+1,m,vc[mr][mc],sc);
del(er);
LEFT-=m,score+=sc;
if(DBG)printf("LFET %d\n",LEFT);
if(DBG)print();
}
return m;
}
int main(){
int n;
bool ll=0;
char chs[20];
init();
cin>>n;
rep(i,n){
LEFT=10*15,score=0;
move=1;
string s(10,'0');
vc.assign(15,s);
rep(i,10){
scanf("%s",chs);
rep(j,strlen(chs))vc[j][10-1-i]=chs[j];
}
if(ll)printf("\n");ll=1;
printf("Game %d:\n\n",cases++);
while(LEFT&&go());
if(LEFT==0)score+=1000;
printf("Final score: %d, with %d balls remaining.\n",score,LEFT);
}
}