UVALive 6755 - Swyper Keyboard

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=&problem=4767&mosmsg=Submission+received+with+ID+1453512


模拟出所有对应字母二元组对应的字符串,保存到map里面。

难点是怎么计算,我写的比较麻烦,对于每一个方块,我用先计算直线与矩形哪条边相交,再DFS那个方向与它相邻的方块。此处有卡精度,比如我就在A Z ABHIJQRYZ这儿卡了一发,因为正确的解是A Z ABHIQRYZ,计算的时候加个eps。然后只要预处理出所有的,最后用的时候再查就可以了。


代码:

#include <iostream>
#include <map>
#include <cstring>
#include <cstdio>
using namespace std;
const double eps = 0.000000001;
typedef pair<char, char> CC;
#define  mp(a,b)  make_pair<char,char>(a,b)
#define U 1
#define UR 2
#define R 3
#define DR 4
#define D 5
#define DL 6
#define L 7
#define UL 8
#define dfsU(rec)  DFS(rect[pos[rec.y+1][rec.x]], U)
#define dfsUR(rec)  DFS(rect[pos[rec.y+1][rec.x+1]], UR)
#define dfsR(rec)  DFS(rect[pos[rec.y][rec.x+1]], R)
#define dfsDR(rec)  DFS(rect[pos[rec.y-1][rec.x+1]], DR)
#define dfsD(rec)  DFS(rect[pos[rec.y-1][rec.x]], D)
#define dfsDL(rec)  DFS(rect[pos[rec.y-1][rec.x-1]], DL)
#define dfsL(rec)  DFS(rect[pos[rec.y][rec.x-1]], L)
#define dfsUL(rec)  DFS(rect[pos[rec.y+1][rec.x-1]], UL)
map<CC, string>memo;
double a, b;
int special;

struct Rect{
    int x, y;
    char ch;
    double u,d,l,r;
}rect[30];
int pos[5][8];

int hor(double x1, double x2, double y){//与水平边相交
    if(special){
        return x1 <= a+eps && a-eps <= x2;
    }else{
        double y1 = a*x1 + b;
        double y2 = a*x2 + b;
        return (y1 <= y+eps && y-eps <= y2) || (y1 >= y-eps && y+eps >= y2);
    }
}

int ver(double y1, double y2, double x){//与垂直边相交
    if(special){
        return 0;
    }else{
        if(a == 0){
            return (y1 <= b+eps && b-eps <= y2) || (y1 >= b-eps && b+eps >= y2);
        }else{
            double x1 = (y1 - b) / a;
            double x2 = (y2 - b) / a;
            return (x1 <= x+eps && x-eps <= x2) || (x1 >= x-eps && x+eps >= x2);
        }
    }
}
Rect S, E;

void calab(){
    double x1 = S.x, x2 = E.x;
    double y1 = S.y, y2 = E.y;
    if(x1 == x2){
        special = 1;
        a = x1;
        return ;
    }else{
        special = 0;
        a = (y2-y1)/(x2-x1);
        b = y1 - a*x1;
    }
}

int caldir(){
    if(S.y < E.y && S.x == E.x) return U;
    if(S.y < E.y && S.x < E.x) return UR;
    if(S.y == E.y && S.x < E.x) return R;
    if(S.y > E.y && S.x < E.x) return DR;
    if(S.y > E.y && S.x == E.x) return D;
    if(S.y > E.y && S.x > E.x) return DL;
    if(S.y == E.y && S.x > E.x) return L;
    if(S.y < E.y && S.x > E.x) return UL;
    return 0;
}

string DFS(Rect rec, int dir){//直线从上一个方块的哪个方向进来
    string ret = "";
    if(rec.ch != '#')
    ret += rec.ch;
    if(rec.ch == E.ch) {
        return ret;
    }
    int up = hor(rec.l, rec.r, rec.u);
    int right = ver(rec.u, rec.d, rec.r);
    int down = hor(rec.l, rec.r, rec.d);
    int left = ver(rec.u, rec.d, rec.l);
    if(dir == D){
        if(down && left) ret += dfsDL(rec);
        else if(down && right) ret += dfsDR(rec);
        else if(left) ret += dfsL(rec);
        else if(right) ret += dfsR(rec);
        else if(down) ret += dfsD(rec);
    }else if(dir == DL){ //UR
        if(down && left) ret += dfsDL(rec);
        else if(left) ret += dfsL(rec);
        else if(down) ret += dfsD(rec);
    }else if(dir == L){ //R
        if(up && left) ret += dfsUL(rec);
        else if(down && left) ret += dfsDL(rec);
        else if(up) ret += dfsU(rec);
        else if(left) ret += dfsL(rec);
        else if(down) ret += dfsD(rec);
    }else if(dir == UL){ //DR
        if(up && left) ret += dfsUL(rec);
        else if(left) ret += dfsL(rec);
        else if(up) ret += dfsU(rec);
    }else if(dir == U){//D
        if(up && left) ret += dfsUL(rec);
        else if(up && right) ret += dfsUR(rec);
        else if(left) ret += dfsL(rec);
        else if(right) ret += dfsR(rec);
        else if(up) ret += dfsU(rec);
    }else if(dir == UR){ //DL
        if(up && right) ret += dfsUR(rec);
        else if(right) ret += dfsR(rec);
        else if(up) ret += dfsU(rec);
    }else if(dir == R){ //L
        if(up && right) ret += dfsUR(rec);
        else if(down && right) ret += dfsDR(rec);
        else if(up) ret += dfsU(rec);
        else if(right) ret += dfsR(rec);
        else if(down) ret += dfsD(rec);
    }else if(dir == DR){//UL
        if(down && right) ret += dfsDR(rec);
        else if(right) ret += dfsR(rec);
        else if(down) ret += dfsD(rec);
    }
    return ret;
}

string calstr(string str){
    string ret = "";
    int len = str.length();
    ret = str[0];
    for(int i = 1; i < len; i++){
        CC cc;
        cc.first = str[i-1];
        cc.second = str[i];
        string tmp = memo[cc];
        ret += tmp.erase(0,1);
    }
    return ret;
}

int main(){
//    freopen("data.in", "r", stdin);
//    freopen("data.out", "w", stdout);
    int m = 0;

    /** 读入方块坐标 **/
    for(int x = 2, y = 4; x <= 6; x++){
        rect[m].x = x;
        rect[m].y = y;
        m++;
    }
    for(int y = 3; y >= 1; y--){
        for(int x = 1; x <= 7; x++){
            rect[m].x = x;
            rect[m].y = y;
            m++;
        }
    }
    rect[m].x = 1;
    rect[m].y = 4;
    m++;
    rect[m].x = 7;
    rect[m].y = 4;
    m++;

    memset(pos, 0, sizeof 0);
    for(int i = 0; i < m; i++){
        pos[rect[i].y][rect[i].x] = i;
        rect[i].ch = 'A'+i;
        rect[i].u = 1.0*rect[i].y+0.5;
        rect[i].r = 1.0*rect[i].x+0.5;
        rect[i].d = 1.0*rect[i].y-0.5;
        rect[i].l = 1.0*rect[i].x-0.5;
    }
    rect[26].ch = '#';
    rect[27].ch = '#';
    for(int y = 4; y >= 1; y--)
    for(int x = 1; x <= 7; x++){
        S = rect[pos[y][x]];
        if(S.ch == '#') continue;
        for(int yy = 4; yy >= 1; yy--)
            for(int xx = 1; xx <= 7; xx++){
                E = rect[pos[yy][xx]];
                if(E.ch == '#') continue;
                CC cc;
                cc.first = S.ch;
                cc.second = E.ch;
                calab();
                memo[cc] = DFS(S, caldir());
            }
    }
//    for(map<CC,string>::iterator it = memo.begin(); it != memo.end(); it++)
//        cout<<it->first.first<<" "<<it->first.second<<" "<<(it->second)<<endl;
    /*** Solve ***/
    int T;
    scanf("%d", &T);
    while(T--){
        int m;
        string sub, str;
        cin>>m>>str;
        int ok  = 0;
        int len;
        str = calstr(str);
        len = str.length();
        while(m--){
            cin>>sub;
            int sublen = sub.length();
            if(ok) continue;
            for(int i = 0, j = 0; i < len && j < sublen; i++){
                while(str[i] == sub[j] && i < len && j < sublen) i++, j++;
                if(j == sublen) ok = 1;
            }
            if(ok) cout<<sub<<endl;
        }
        if(!ok) cout<<"NO SOLUTION"<<endl;
    }
    return 0;
}


by howard


你可能感兴趣的:(模拟,DFS,la)