Google Code Jam 2019 Round 1A Pylons(爆搜+贪心)

前提是你 提交于 2020-04-07 16:29:46

这道题,对于小数据,直接上爆搜,也就是把每个点所有能到的地方都用vector存一下,当0的时候,任意选点,之后再从所有能到的地方选点。因为第一问数据非常小,所以算法合格

但是第二问数据比较大,可以采用贪心算法(没有证明正确性,但是跑过了所有数据),在上面的前提下,每次选点都从合法范围最大的点出发

从直觉上来看,这样确实能够有更多的选择性和容错率,但是没有证明他的正确性。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<map>
#include<algorithm>
#include<queue>
#include<set>
#define ull unsigned long long
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
typedef pair<int,pair<int,int> > plll;
const int N=1e5+10;
const int inf=0x3f3f3f3f;
vector<pll> g[300][300];
vector<pll> ans;
int st[301][301];
int flag[301][301];
int px[N],py[N];
bool dfs(int depth,int x,int y,int n,int m){
    int i;
    if(depth==n*m){
        for(i=0;i<n*m;i++){
            ans.push_back(pll{px[i],py[i]});
        }
        return true;
    }
    if(depth==0){
        for(int i=1; i <=n;i++)
            for (int j =1; j<=m;j++){
                flag[i][j] = true;
                px[0] = i;
                py[0] = j;
                if(dfs(1, i, j, n, m))
                    return true;
                flag[i][j] = false;
            }
    }
    else{
        pair<int,pll> mov[10010];
        int idx=0;
        for(i=0;i<g[x][y].size();i++){
            int u=g[x][y][i].first;
            int v=g[x][y][i].second;
            if(!flag[u][v])
                mov[idx++]=make_pair(st[u][v],pll{u,v});
        }
        sort(mov,mov+idx);
        for(i=0;i<idx;i++){
            int u=mov[i].second.first;
            int v=mov[i].second.second;
            int j;
            flag[u][v]=1;
            px[depth]=u;
            py[depth]=v;
            for(j=0;j<g[u][v].size();j++){
                int a=g[u][v][j].first;
                int b=g[u][v][j].second;
                st[a][b]--;
            }
            if(dfs(depth+1,u,v,n,m))
                return true;
            for(j=0;j<g[u][v].size();j++){
                int a=g[u][v][j].first;
                int b=g[u][v][j].second;
                st[a][b]++;
            }
            flag[u][v]=0;
        }
    }
    return false;
}
int main(){
    int t;
    cin>>t;
    int cnt=0;
    while(t--){
        cnt++;
        int r,c;
        cin>>r>>c;
        ans.clear();
        memset(st,0,sizeof st);
        memset(flag,0,sizeof flag);
        int i,j;
        int x,y;
        for(i=1;i<=r;i++){
            for(j=1;j<=c;j++){
                g[i][j].clear();
                for(x=1;x<=r;x++){
                    for(y=1;y<=c;y++){
                        if(i!=x&&j!=y&&i-j!=x-y&&i+j!=x+y){
                            g[i][j].push_back(pll{x,y});
                            st[i][j]++;
                        }
                    }
                }
            }
        }
        printf("Case #%d: ",cnt);
        if(!dfs(0,-1,-1,r,c)){
            cout<<"IMPOSSIBLE"<<endl;
        }
        else{
            cout<<"POSSIBLE"<<endl;
            for(i=0;i<ans.size();i++){
                cout<<ans[i].first<<" "<<ans[i].second<<endl;
            }
        }
    }
}
View Code

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!