zoukankan      html  css  js  c++  java
  • 题解-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;
    }
    

    祝大家学习愉快!

  • 相关阅读:
    URAL 2046 A
    URAL 2056 Scholarship 水题
    Codeforces Gym 100286I iSharp 水题
    Codeforces Gym H. Hell on the Markets 贪心
    Codeforces Gym 100286G Giant Screen 水题
    Codeforces Gym 100286B Blind Walk DFS
    Codeforces Gym 100286F Problem F. Fibonacci System 数位DP
    Codeforces Gym 100286A. Aerodynamics 计算几何 求二维凸包面积
    Codeforces Gym 100418K Cards 暴力打表
    Codeforces Gym 100418J Lucky tickets 数位DP
  • 原文地址:https://www.cnblogs.com/George1123/p/13695150.html
Copyright © 2011-2022 走看看