2014年acm-icpc广州regional网络赛经历

一开始就在做1004,然后做了一开始看成是每一把钥匙只有一把,然后就wa了,下面是wa了的代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
#define inf (1<<29)
const int maxn = 110;
char s[maxn][maxn];
int mp[maxn][maxn];
bool is_s[maxn][maxn];
bool vis[maxn][maxn];
int dir[4][2] = {1,0,-1,0,0,1,0,-1};
struct node {
    int x , y;
}a[12];
//node pre[maxn][maxn];
int n , m;
queue <node> q;
int ans;
bool inmap(int x,int y) {
    return x >= 0 && x < n && y >= 0 && y < n;
}
bool check()
{
    for(int i=0;i<=m+1;i++) {
        int x = a[i].x , y = a[i].y;
        if(mp[x][y] == -1) return false;
    }
    return true;
}
void debug_output(int id) {
    printf("%d turn:\n" , id);
    for(int i=0;i<n;i++) {
        for(int j=0;j<n;j++) printf("%3d" , mp[i][j]);
        puts("");
    }
    for(int i=0;i<=m+1;i++) {
        printf("a[%d].x is %d , a[%d].y is %d\n",i,a[i].x,i,a[i].y);
    }
}
void backtrack(int x,int y) {
    if(mp[x][y] == 0) return;
    int tmp = 1; if(is_s[x][y]) tmp += 1;
    is_s[x][y] = false;
    for(int i=0;i<4;i++) {
        int xx = x + dir[i][0];
        int yy = y + dir[i][1];
        if(!inmap(xx,yy) || s[xx][yy] == '#') continue;
        if(mp[xx][yy] + tmp == mp[x][y]) {
            backtrack(xx,yy);
            return;
        }
    }
    return;
}
bool dfs(int id) {
    //printf("check %d\n" , id);
    memset(vis,false,sizeof(vis));
    memset(mp,-1,sizeof(mp));
    int x = a[id].x , y = a[id].y;
    mp[x][y] = 0;
    node u , v; u.x = x; u.y = y;
    while(!q.empty()) q.pop();
    q.push(u);
    while(!q.empty()) {
        u = q.front();
        q.pop();
        vis[u.x][u.y] = false;
        for(int i=0;i<4;i++) {
            x = u.x + dir[i][0];
            y = u.y + dir[i][1];
            if(!inmap(x,y) || s[x][y] == '#') continue;
            int tmp = 1; if(is_s[x][y]) tmp += 1;
            if(mp[x][y] == -1 || mp[x][y] > mp[u.x][u.y] + tmp) {
                //pre[x][y].x = u.x;
                //pre[x][y].y = u.y;
                mp[x][y] = mp[u.x][u.y] + tmp;
                if(!vis[x][y]) {
                    vis[x][y] = true;
                    v.x = x; v.y = y;
                    q.push(v);
                }
            }
        }
    }
    debug_output(id);
    if(id == 0 && !check()) return false;
    ans += mp[ a[id+1].x ][ a[id+1].y ];
    printf("tmp ans is %d\n" , ans);
    if(id == m) return true;
    backtrack(a[id+1].x , a[id+1].y);
    dfs(id+1);
    return true;
}
void init() {
    for(int i=0;i<n;i++) scanf("%s" , s[i]);
    memset(is_s,false,sizeof(is_s));
    for(int i=0;i<n;i++) {
        for(int j=0;j<n;j++) {
            if(s[i][j] == 'K') { a[0].x = i; a[0].y = j; }
            else if(s[i][j] == 'T') { a[m+1].x = i; a[m+1].y = j; }
            else if(s[i][j] == 'S') { is_s[i][j] = true; }
            else if(s[i][j] >= '1' && s[i][j] <= '9') {
                int num = s[i][j] - '0';
                a[num].x = i; a[num].y = j;
            }
        }
    }
}
int main() {
    while(~scanf("%d%d" , &n,&m) && n+m) {
        init();
        ans = 0;
        if(!dfs(0)) puts("impossible");
        else printf("%d\n" , ans);
    }
    return 0;
}

改进了之后还是wa了,下面是改成多把钥匙的wa的代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
#define inf (1<<29)
const int maxn = 110;
char s[maxn][maxn];
int mp[maxn][maxn];
bool is_s[maxn][maxn];
bool vis[maxn][maxn];
bool is_ss[maxn][maxn];
int dir[4][2] = {1,0,-1,0,0,1,0,-1};
struct node {
    int x , y;
};
vector<node> a[12];
//node pre[maxn][maxn];
int n , m;
queue <node> q;
int ans;
bool inmap(int x,int y) {
    return x >= 0 && x < n && y >= 0 && y < n;
}
bool check()
{
    for(int i=0;i<=m+1;i++) {
        bool ok = false;
        int sz = a[i].size();
        for(int j=0;j<sz;j++) {
            int x = a[i][j].x , y = a[i][j].y;
            if(mp[x][y] != -1) { ok = true; break; }
        }
        if(!ok) return false;
    }
    return true;
}
void backtrack(int x,int y) {
    if(mp[x][y] == 0) return;
    int tmp = 1; if(is_s[x][y]) tmp += 1;
    is_s[x][y] = false;
    for(int i=0;i<4;i++) {
        int xx = x + dir[i][0];
        int yy = y + dir[i][1];
        if(!inmap(xx,yy) || s[xx][yy] == '#') continue;
        if(mp[xx][yy] + tmp == mp[x][y]) {
            backtrack(xx,yy);
            return;
        }
    }
    return;
}
/*
void gogo() {
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            is_ss[i][j] = is_s[i][j];
}
void backback() {
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            is_s[i][j] = is_ss[i][j];
}
*/
bool dfs(int id,int x,int y,int sum) {
    //printf("id: %d , x:%d , y:%d , tmp sum: %d\n" , id,x,y,sum);
    memset(vis,false,sizeof(vis));
    memset(mp,-1,sizeof(mp));
    mp[x][y] = 0;
    node u , v; u.x = x; u.y = y;
    while(!q.empty()) q.pop();
    q.push(u);
    while(!q.empty()) {
        u = q.front();
        q.pop();
        vis[u.x][u.y] = false;
        for(int i=0;i<4;i++) {
            x = u.x + dir[i][0];
            y = u.y + dir[i][1];
            if(!inmap(x,y) || s[x][y] == '#') continue;
            int tmp = 1; if(is_s[x][y]) tmp += 1;
            if(mp[x][y] == -1 || mp[x][y] > mp[u.x][u.y] + tmp) {
                //pre[x][y].x = u.x;
                //pre[x][y].y = u.y;
                mp[x][y] = mp[u.x][u.y] + tmp;
                if(!vis[x][y]) {
                    vis[x][y] = true;
                    v.x = x; v.y = y;
                    q.push(v);
                }
            }
        }
    }
    //debug_output(id);
    if(id == 0 && !check()) return false;
    if(id == m) {
        int x = a[m+1][0].x , y = a[m+1][0].y;
        if(sum + mp[x][y] < ans) ans = sum + mp[x][y];
        return true;
    }
    int sz = a[id+1].size();
    //gogo();
    bool is_ss[maxn][maxn];
    for(int i=0;i<n;i++) for(int j=0;j<n;j++) is_ss[i][j] = is_s[i][j];
    for(int i=0;i<sz;i++) {
        int x = a[id+1][i].x , y = a[id+1][i].y;
        if(mp[x][y] == -1) continue;
        backtrack(x , y);
        dfs(id+1 , x , y , sum+mp[x][y]);
        //backback();
        for(int i=0;i<n;i++) for(int j=0;j<n;j++) is_s[i][j] = is_ss[i][j];
    }
    return true;
}
void init() {
    for(int i=0;i<n;i++) scanf("%s" , s[i]);
    memset(is_s,false,sizeof(is_s));
    node u;
    for(int i=0;i<=m+1;i++) a[i].clear();
    for(int i=0;i<n;i++) {
        for(int j=0;j<n;j++) {
            if(s[i][j] == 'K') { u.x = i; u.y = j; a[0].push_back(u); }
            else if(s[i][j] == 'T') { u.x = i; u.y = j; a[m+1].push_back(u); }
            else if(s[i][j] == 'S') { is_s[i][j] = true; }
            else if(s[i][j] >= '1' && s[i][j] <= '9') {
                int num = s[i][j] - '0';
                u.x = i; u.y = j;
                a[num].push_back(u);
            }
        }
    }
}

int main() {
    while(~scanf("%d%d" , &n,&m) && n+m) {
        init();
        ans = inf;
        if(!dfs(0 , a[0][0].x , a[0][0].y , 0)) puts("impossible");
        else printf("%d\n" , ans);
    }
    return 0;
}

然后想用用dfs暴力吧,结果TLE了,下面是TLE的代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
#define inf (1<<29)
const int maxn = 110;
int dir[4][2] = {1,0,-1,0,0,1,0,-1};
char s[maxn][maxn];
int n , m;
int point[maxn][maxn] , vtime[maxn][maxn];
int ans;
int vis[12][maxn][maxn];
bool inmap(int x,int y) {
    return x >= 0 && x < n && y >= 0 && y < n;
}
void dfs(int id,int x,int y , int step) {
    //printf("id:%d , x:%d , y:%d , step:%d\n",id,x,y,step);
    if(step >= ans) return;
    if(id == m+1) {
        if(step < ans) ans = step;
        return;
    }
    for(int i=0;i<4;i++) {
        int xx = x + dir[i][0] , yy = y + dir[i][1];
        if(!inmap(xx , yy) || s[xx][yy] == '#' || vis[id][xx][yy] <= step) continue;
        vis[id][xx][yy] = step;
        if(point[xx][yy] == id+1) {
            //memset(vis[id+1] , false , sizeof(vis[id+1]));
            for(int j=0;j<n;j++)
                for(int k=0;k<n;k++)
                    vis[id+1][j][k] = inf;
            vis[id+1][xx][yy] = step+1;
            dfs(id+1 , xx , yy , step+1);
            for(int j=0;j<n;j++)
                for(int k=0;k<n;k++)
                    if(s[j][k] == 'S' && vtime[j][k] > id) vtime[j][k] = inf;
        }
        else if(s[xx][yy] == 'S' && vtime[xx][yy] > id) {
            vtime[xx][yy] = id;
            dfs(id , xx , yy , step+2);
        }
        else {
            dfs(id , xx , yy , step+1);
        }
    }
    return;
}
int sx , sy;
void init() {
    for(int i=0;i<n;i++) scanf("%s" , s[i]);
    for(int i=0;i<n;i++)
    for(int j=0;j<n;j++) {
        if(s[i][j] == 'K') { sx = i; sy = j; point[i][j] = 0; }
        else if(s[i][j] == 'T') { point[i][j] = m+1; }
        else if(s[i][j] == 'S') { vtime[i][j] = inf; point[i][j] = -1; }
        else if(s[i][j] >= '1' && s[i][j] <= '9') {
            int num = s[i][j] - '0';
            point[i][j] = num;
        }
        else point[i][j] = -1;
    }
    for(int i=0;i<=m+1;i++)
        for(int j=0;j<n;j++)
            for(int k=0;k<n;k++)
                vis[i][j][k] = inf;
    ans = inf;
}
//void before_bfs()
//bool before_check()
int main() {
    while(~scanf("%d%d" , &n,&m) && n+m) {
        init();
        dfs(0,sx,sy,0);
        if(ans == inf) puts("impossible");
        else printf("%d\n" , ans);
    }
    return 0;
}

然后想想我这个老人应该省省了,明显就是贡献几个wa的人嘛!战斗了明显为负。

算了我还是回去安静的做一个美男子吧~

2014年9月30日补充:

后来在某一天晚上回去的路上碰到了12级最厉害的学弟LB,然后LB告诉了我他当时的做法是:枚举每一个有蛇的房间有没有走到,然后进行搜索。(不过走路有的时候不看人的毛病还是没有改过来,LB说他叫了我三四遍~然后我才发现我刚才是从他后面超过去的~~~竟然没看人真的是不好意思,不过也不能怪我,他不是萌妹子我没有太大兴趣~~)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值