• 题解-CF1282E The Cake Is a Lie


    题面

    CF1282E The Cake Is a Lie

    (T) 组测试数据。每次给一个 (n) 边形的三角剖分,求节点顺序和剖分顺序。

    数据范围:(3le nle 10^5)(sum nle 10^5)


    蒟蒻解

    这题在炫酷的代码和外表下是一个大水题。

    对于每一个剖下来的三角形的边,要么是原多边形的边,要么是割的边。

    多边形的边在所有三角形的边中出现 (1) 次,割边在所有三角形中出现 (2) 次。

    所以用 map 记录每条边的出现次数。

    然后从一个三角形出发,然后用 dfs 合并上出现 (2) 次的边的三角形即可。

    对于第一个询问可以用一个环状链表,第二个可以回溯加 vector

    为了方便,代码中从一个有两条原多边形的边的三角形开始,这样每次就最多有两边要合并三角形了。


    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    //Start
    typedef long long ll;
    typedef double db;
    #define mp(a,b) make_pair((a),(b))
    #define x first
    #define y second
    #define be(a) (a).begin()
    #define en(a) (a).end()
    #define sz(a) int((a).size())
    #define pb(a) push_back(a)
    #define R(i,a,b) for(int i=(a),I=(b);i<I;i++)
    #define L(i,a,b) for(int i=(b)-1,I=(a)-1;i>I;i--)
    const int iinf=0x3f3f3f3f;
    const ll linf=0x3f3f3f3f3f3f3f3f;
    
    //Data
    const int N=1e5;
    int n,nex[N],ea[N-2],eb[N-2],ec[N-2];
    bool vis[N]; vector<int> ans;
    map<pair<int,int>,vector<pair<int,int>>> mp;
    #define pa(x,y) mp(min(x,y),max(x,y))
    #define an(x,y) mp[pa(x,y)]
    
    //Main
    void solve(pair<int,int> e){
    	if(nex[e.y]==e.x) swap(e.x,e.y); 
    	vector<pair<int,int>> tv=an(e.x,e.y);
    	int ez=vis[tv[0].x]?tv[1].x:tv[0].x; 
    	int et=vis[tv[0].x]?tv[1].y:tv[0].y;
    	vis[ez]=true,nex[e.x]=ez,nex[ez]=e.y;
    	if(sz(an(e.x,ez))>=2) solve(mp(e.x,ez));
    	if(sz(an(e.y,ez))>=2) solve(mp(e.y,ez));
    	ans.pb(et);
    }
    void Main(){
    	cin>>n,ans.clear();
    	fill(nex,nex+n,-1);
    	fill(vis,vis+n,false);
    	if(n==3){
    		cin>>ea[0]>>eb[0]>>ec[0];
    		cout<<"1 2 3
    1
    ";
    		return;
    	}
    	mp.clear();
    	R(i,0,n-2){
    		cin>>ea[i]>>eb[i]>>ec[i];
    		--ea[i],--eb[i],--ec[i];
    		an(ea[i],eb[i]).pb(mp(ec[i],i));
    		an(ea[i],ec[i]).pb(mp(eb[i],i));
    		an(eb[i],ec[i]).pb(mp(ea[i],i));
    	}
    	int s=-1; pair<int,int> e(-1,-1);
    	R(i,0,n-2){
    		int cnt=0;
    		if(sz(an(ea[i],eb[i]))==2) cnt++,e=pa(ea[i],eb[i]);
    		if(sz(an(ea[i],ec[i]))==2) cnt++,e=pa(ea[i],ec[i]);
    		if(sz(an(eb[i],ec[i]))==2) cnt++,e=pa(eb[i],ec[i]);
    		if(cnt==1){s=i;break;}
    	}
    	nex[ea[s]]=eb[s],nex[eb[s]]=ec[s],nex[ec[s]]=ea[s];
    	vis[ea[s]]=vis[eb[s]]=vis[ec[s]]=true,ans.pb(s);
    	solve(e);
    	int now=0;
    	R(i,0,n) cout<<now+1<<' ',now=nex[now];cout<<'
    ';
    	for(int x:ans) cout<<x+1<<' ';cout<<'
    ';
    }
    int main(){
    	ios::sync_with_stdio(0);
    	cin.tie(0),cout.tie(0);
    	int tn; cin>>tn;
    	R(ta,0,tn) Main();
    	return 0;
    }
    

    祝大家学习愉快!

  • 相关阅读:
    关于Faster-RCNN训练细节
    tensorflow 使用tfrecords创建自己数据集
    深度学习(tensorflow) —— 自己数据集读取opencv
    Tensorflow常见函数case argmax equal
    pandas dataframe类型操作
    celery 启动命令
    pipenv 虚拟环境新玩法
    拉取远程分支
    odoo 开发 context 上下文的用法
    odoo 二次开发的方法
  • 原文地址:https://www.cnblogs.com/George1123/p/13695150.html
Copyright © 2020-2023  润新知