• HDU6627 equation


    题目链接

    题意:

    两个长度为(n)的数组(a)(b)和一个正整数(C),计算有多少个(x)满足:

    [sum_{i=1}^n|a_i cdot x+b_i|=C ]

    思路:

    该函数为分段函数,每段的转折点为(-frac{b_i}{a_i}),先把转折点排序,计最开始的函数值为(x cdot suma + sumb),每过一段,就会有一个(|a_i cdot x+b_i|)(a_i cdot x+b_i)变为(-a_i cdot x - b_i),那么(suma-2 cdot a_i),(sum_b)变为 (sumb-2 cdot b_i)。每段函数都是线性的,大力枚举计算即可。然后对答案进行排序(博主忘记排序结果Wa到爆炸)。

    代码:

    #include<bits/stdc++.h>
    
    using namespace std;
    const int N = 2e5+100;
    struct node{
    	long long a,b;
    }s[N];
    int n;double c;
    bool cmp(node x,node y){
    	return (x.b*y.a)<(x.a*y.b);
    }
    bool cmp2(pair<long long, long long> a,pair<long long,long long> b){
    	return a.first*b.second<a.second*b.first;
    }
    vector<pair<long long,long long>> ans;
    void make(long long x,long long y){
    	if(x==0){
    		y=1;
    		ans.push_back({x,y});return ;
    	}
    	long long gg=__gcd(x,y);
    	x/=gg;y/=gg;
    	if(y<=0){
    		x=-x;y=-y;
    	}
    	ans.push_back({x,y});
    	return ;
    }
    void solve(){
    	ans.clear();
    	scanf("%d %lf",&n,&c);
    	long long sa=0;long long sb=0;
    	for(int i=1;i<=n;i++){
    		 scanf("%lld %lld",&s[i].a,&s[i].b);
    		 sa+=s[i].a;
    		 sb+=s[i].b;
    	}
    	sort(s+1,s+n+1,cmp);
    	double up=9999999999999;
    	double down=-1.0*double(s[1].b*sa)/double(s[1].a)+sb;
    	if(c>=down&&c<=up){
    		long long u=(long long)c-sb;
    		long long d=sa;
    		make(u,d);
    	}
    	bool flag=0;
    	for(int i=2;i<=n;i++){
    		double nowr=(-1.0*double(s[i].b)*(sa-2*s[i-1].a)/double(s[i].a))+(sb-2*s[i-1].b);
    		double bef=(-1.0*double(s[i-1].b)/double(s[i-1].a))*(sa)+(sb);
    		up=max(nowr,bef);
    		down=min(nowr,bef);
    		if(up==down&&up==c){
    			flag=1;break;
    		}
    		sa-=2*s[i-1].a;
    		sb-=2*s[i-1].b;
    		if(c>=down&&c<=up){
    			long long u=(long long)c-sb;
    			long long d=sa;
    			make(u,d);			
    		}
    	}
    	sa-=2*s[n].a;
    	sb-=2*s[n].b;
    	up=9999999999999;
    	down=-1.0*double(s[n].b*sa)/double(s[n].a)+sb;
    	if(c>=down&&c<=up){
    		long long u=c-sb;
    		long long d=sa;
    		make(u,d);
    	}
    	if(flag) puts("-1");
    	else{
    		sort(ans.begin(),ans.end(),cmp2);
    		int siz=unique(ans.begin(),ans.end())-ans.begin();
    		printf("%d",siz);
    		for(int i=0;i<(int)siz;i++) printf(" %lld/%lld", ans[i].first,ans[i].second);
    		puts("");
    	}
    }
    int main(){
    	int T;scanf("%d",&T);
    	while(T--) solve();
    	return 0;
    }
    
    /*
    2 6
    0 4
    -2 -6
    */
    
  • 相关阅读:
    逆向工程工具介绍2-IDA
    汇编语言基础-1 基本语言元素
    Python常用标准库1-Turtle,Random,Time和Datetime
    Python的模块、包和库的概念
    Go语言的函数修饰符
    物理层2-物理层下面的传输媒体
    数据分析之两种用户分群方法(RFM和聚类)
    区间估计与假设检验公式
    源码分析过滤器与拦截器的区别
    Springboot拦截器使用及其底层源码剖析
  • 原文地址:https://www.cnblogs.com/codancer/p/12232406.html
Copyright © 2020-2023  润新知