2014北京邀请赛 A:A Matrix 构造+贪心

来源:互联网 发布:南京mac专柜价格 编辑:程序博客网 时间:2024/05/24 05:02

题目连接: http://acm.bnu.edu.cn/bnuoj/problem.php?search=2014+ACM-ICPC+Beijing+Invitational+Programming+Contest

题解:显然,如果在第i行(i > 1)有一个数,那么这个数一定是被第i-1行一个比他小的数挤下来的

           那么就可以从最后一行开始不断往上找比他小的数, 直到第一行,形成一个个链,最后再从第一行开始把链一个个倒着输出出来就是答案了。

   如果有个数找不到链了那么说明无解

#include<iostream>#include<cstdio>#include<cstdlib>#include<algorithm>#include<cstring>#include<string>#include<vector>#include<cmath>#include<set>using namespace std;#define CLR(a,b) memset(a,b,sizeof(a))const int N = 100000+20;int n,m;vector<int> a[N];set<int> s[N];set<int>::iterator ite;int pre[N];int nxt[N];bool vis[N];vector<int> ans;bool work(int l,int num){    if(l < 0)return 1;    if(s[l].size() == 0)return 0;    set<int>::iterator kte = s[l].lower_bound(num);    if(kte == s[l].begin())return 0;    kte--;    pre[num] = *kte;    nxt[*kte] = num;    s[l].erase(kte);    return 1;    //return work(l-1, *kte);}void gao(int num){    vector<int> tmp;    while(nxt[num] != -1){        vis[num] = 1;        tmp.push_back(num);        num = nxt[num];    }    vis[num] = 1;    ans.push_back(num);    for(int i = tmp.size() - 1 ;i >= 0; i --)ans.push_back(tmp[i]);}void solve(){    CLR(pre,-1);    CLR(nxt,-1);    CLR(vis,0);    bool ok = 1;    ans.clear();    for(int i = m-1 ; i > 0 ; i --){        for(int j = a[i].size()-1; j >= 0 ; j--){            if(!work(i-1, a[i][j])){                ok = 0;                break;            }        }        if(!ok)break;    }    if(!ok){        puts("No solution");    }else{        for(int i = 0 ; i < m ; i ++){            for(int j = 0 ;j < a[i].size(); j ++){                if(!vis[a[i][j]]){                    gao(a[i][j]);                }            }        }        for(int i = 0; i < ans.size() ; i ++){            if(i > 0)printf(" ");            printf("%d",ans[i]);        }        puts("");    }} int main() {     int T,cas = 0;     scanf("%d",&T);     while(T--){         cas ++;         printf("Case #%d: ",cas);         scanf("%d%d",&n,&m);         for(int i = 0 ; i < m ; i ++)a[i].clear();         for(int i = 0 ; i < m ; i ++){             int num;             scanf("%d",&num);             while(num--){                 int x;                 scanf("%d",&x);                 a[i].push_back(x);             }         }         bool ok = 1;         for(int i = 0 ; i < m ; i ++){             for(int j = 1 ;j < a[i].size() ;j ++){                 if(a[i][j] < a[i][j-1])ok = 0;             }         }         for(int i = 0 ;i < m ;i ++){             s[i].clear();             for(int j = 0; j < a[i].size() ; j ++){                 s[i].insert(a[i][j]);             }         }         if(!ok){             puts("No solution");         }else{             solve();         }     }     return 0; } /* 100 7 3 3 1 4 6 3 2 5 7 1 3 */


0 0