Topcoder SRM 559 ToyTrain

解题大概有以下几个思路
首先判一定不能有解 有三种情况
1.图中没有’A’或’B’
2.题目中给到的’S’点没有用到
3.有一个点非’A’非’B’点被用到了两次 ,用于横竖两个方向 那必然无解了,因为方向已经规定了
然后有解的情况
同一行中’A’的数量等于’B’,同一列同理。(显然的。。)
按照两个两个来分组 必然是A-B 或者B-A 组合 A后面总不能直接连着自己吧

我的做法大概是先暴力判掉不能满足条件的几种先
然后在所有的’A’和‘B’横竖都进行建边 然后标记一下 记录一下cnt 最后可以用cnt来判掉无解的第二第三种情况
总的来讲 这是一道神题

#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <string.h>

using namespace std;


class ToyTrain {
    int cnt[55][55];
    int n,m;
    bool mark[10];
public:
    int getMinCost(vector <string> field) {
        int ans=0;
        memset(cnt,0,sizeof(cnt));
        memset(mark,0,sizeof(mark));
        n=field.size();
        m=field[0].size();
        for(int i=0;i<n;i++){
            int cntA=0,cntB=0;
            for(int j=0;j<m;j++){
                if(field[i][j]=='A')cntA++;
                else if(field[i][j]=='B')cntB++;
            }
            if(cntA!=cntB)return -1;
        }
        int cnt1=0,cnt2=0;
        for(int i=0;i<n;i++){
            for(int j=0;j<field[i].size();j++){
                if(field[i][j]=='A')cnt1++;
                else if(field[i][j]=='B')cnt2++;
            }
        }
        if(cnt1==0||cnt2==0)return -1;
        for(int i=0;i<m;i++){
            int cntA=0,cntB=0;
            for(int j=0;j<n;j++){
                if(field[j][i]=='A')cntA++;
                else if(field[j][i]=='B')cntB++;
            }
            if(cntA!=cntB)return -1;
        }
        for(int i=0;i<n;i++){
            int j=0;
            bool fA=0,fB=0;
            int xA=-1,xB=-1;
            while(j<m){
                if(field[i][j]=='.'||field[i][j]=='S'||(field[i][j]>='1'&&field[i][j]<='9')){
                    j++;
                    continue;
                }
                if(field[i][j]=='A'){
                    if(fB){
                        for(int k=xB;k<=j;k++)cnt[i][k]++;
                        fB=0;
                        j++;
                        continue;
                    }
                    else {
                        xA=j;
                        fA=1;
                        j++;
                        continue;
                    }
                }
                else if(field[i][j]=='B'){
                    if(fA){
                        for(int k=xA;k<=j;k++)cnt[i][k]++;
                        fA=0;
                        j++;
                        continue;
                    }
                    else {
                        xB=j;fB=1;j++;
                        continue;
                    }
                }
            }
        }
        for(int i=0;i<m;i++){
            int j=0;
            bool fA=0,fB=0;
            int xA=-1,xB=-1;
            while(j<n){
                if(field[j][i]=='.'||field[j][i]=='S'||(field[j][i]>='1'&&field[j][i]<='9')){
                    j++;
                    continue;
                }
                if(field[j][i]=='A'){
                    if(fB){
                        for(int k=xB;k<=j;k++)cnt[k][i]++;
                        fB=0;
                        j++;
                        continue;
                    }
                    else {
                        xA=j;
                        fA=1;
                        j++;
                        continue;
                    }
                }
                else if(field[j][i]=='B'){
                    if(fA){
                        for(int k=xA;k<=j;k++)cnt[k][i]++;
                        fA=0;
                        j++;
                        continue;
                    }
                    else {
                        xB=j;fB=1;j++;
                        continue;
                    }
                }
            }
        }
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(field[i][j]=='A'||field[i][j]=='B')continue;
                if(field[i][j]=='S'&&!cnt[i][j])return -1;
                if(cnt[i][j]==2&&(field[i][j]!='A'||field[i][j]!='B'))return -1;
                else if((field[i][j]>='1'&&field[i][j]<='9')&&cnt[i][j]){
                    if(!mark[field[i][j]-'0']){
                        mark[field[i][j]-'0']=1;
                        ans+=field[i][j]-'0';
                    }
                }
            }
        }
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值