• bzoj4429: [Nwerc2015] Elementary Math小学数学


    先把所有可能的答案算出来,每个算式一个点,每个结果一个点,然后如果一个算式能算出一个结果,那么就连一条边

    然后跑匈牙利,没有完美匹配就是impossible

    每个算式最多有3个结果,所以边数是O(n)的,所以匈牙利的复杂度就是O(n^2)的

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #include <map>
    #define ll long long
    #define N 77777
    #define M 77777
    
    using namespace std;
    inline int read(){
    	int ret=0;char ch=getchar();
    	bool flag=0;
    	while (ch<'0'||ch>'9'){
    		flag=ch=='-';
    		ch=getchar();
    	}
    	while ('0'<=ch&&ch<='9'){
    		ret=ret*10-48+ch;
    		ch=getchar();
    	}
    	return flag?-ret:ret;
    }
    
    struct edge{
    	int adj,next,op;
    	edge(){}
    	edge(int _adj,int _next,int _op):adj(_adj),next(_next),op(_op){}
    } e[M];
    int n,g[N],m;
    void AddEdge(int u,int v,int op){
    	e[++m]=edge(v,g[u],op);g[u]=m;
    }
    
    int fx[N],fy[N],fop[N];
    bool vis[N/3];
    int dfs(int u){
    	if (vis[u]) return 0;
    	vis[u]=1;
    	for (int i=g[u];i;i=e[i].next){
    		int v=e[i].adj;
    		if (!fy[v]||dfs(fy[v])){
    			fy[v]=u;fx[u]=v;fop[u]=e[i].op;
    			return 1;
    		}
    	}
    	return 0;
    }
    
    
    char ch[3]={'+','-','*'};
    inline ll calc(ll x,ll y,int op){
    	if (op==0) return x+y;
    	else if (op==1) return x-y;
    	else return x*y;
    }
    
    ll a[N],b[N];
    map<ll,int> s;int cnt;
    
    int main(){
    	n=read();
    	s.clear();
    	map<ll,int>::iterator it;
    	ll tmp;
    	for (int i=1;i<=n;++i){
    		a[i]=read();b[i]=read();
    		for (int op=0;op<3;++op){
    			it=s.find(calc(a[i],b[i],op));
    			if (it==s.end()) s.insert(make_pair(calc(a[i],b[i],op),++cnt));
    			AddEdge(i,s.find(calc(a[i],b[i],op))->second,op);
    		}
    	}
    	
    	int tot=0;
    	memset(fx,0,sizeof(fx));
    	memset(fy,0,sizeof(fy));
    	for (int i=1;i<=n;++i)if (!fx[i]){
    		memset(vis,0,sizeof(vis));
    		tot+=dfs(i);
    	}
    	if (tot<n){puts("impossible");return 0;}
    	for (int i=1;i<=n;++i)
    		printf("%lld %c %lld = %lld
    ",a[i],ch[fop[i]],b[i],calc(a[i],b[i],fop[i]));
    	return 0;
    }
    

      

  • 相关阅读:
    如何编写vue的javascript代码结构
    二进制文件下载兼容写法
    swtich
    报错:Uncaught ReferenceError: JSENCRYPT_VERSION is not defined
    use application gateway to expose aks service over http/https
    quicksort和第k小元素问题
    quick sort
    高精度加法
    滑动窗口的最大值
    字典树
  • 原文地址:https://www.cnblogs.com/wangyurzee7/p/5314642.html
Copyright © 2020-2023  润新知