zoukankan      html  css  js  c++  java
  • 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
    */
    
  • 相关阅读:
    背水一战 Windows 10 (61)
    背水一战 Windows 10 (60)
    背水一战 Windows 10 (59)
    背水一战 Windows 10 (58)
    背水一战 Windows 10 (57)
    背水一战 Windows 10 (56)
    背水一战 Windows 10 (55)
    背水一战 Windows 10 (54)
    背水一战 Windows 10 (53)
    背水一战 Windows 10 (52)
  • 原文地址:https://www.cnblogs.com/codancer/p/12232406.html
Copyright © 2011-2022 走看看