http://acm.hdu.edu.cn/showproblem.php?pid=6627
题意:解绝对值方程并统计解的个数。
解法:签到题,直接模拟小学数学学的零点分段法即可。(数据多直接cin,cout会T,还以为是算法有问题...
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn = 1e5+10; 5 ll s1[maxn],s2[maxn]; 6 7 struct node{ 8 ll a,b; 9 double s; 10 }g[maxn]; 11 12 bool cmp(node p,node q){ 13 return p.s>q.s; 14 } 15 16 struct note{ 17 ll x,y; 18 double s; 19 }v[maxn]; 20 21 bool cmp1(note p1,note q1){ 22 return p1.s<q1.s; 23 } 24 25 map<double,int> ma; 26 27 int main(){ 28 ios::sync_with_stdio(0); 29 cin.tie(0); 30 cout.tie(0); 31 int t; 32 cin>>t; 33 ll n,c; 34 while(t--){ 35 int cnt = 0; 36 ma.clear(); 37 cin>>n>>c; 38 for(ll i=1;i<=n;i++){ 39 cin>>g[i].a>>g[i].b; 40 g[i].s = -1.0*g[i].b/g[i].a; 41 } 42 sort(g+1,g+n+1,cmp); 43 s1[0] = 0; s2[0] = 0; 44 for(ll i=1;i<=n;i++){ 45 s1[i] = s1[i-1]+g[i].a; 46 s2[i] = s2[i-1]+g[i].b; 47 } 48 int flag = 0; 49 for(ll i=0;i<=n;i++){ 50 ll a1 = s1[n]-2*s1[i]; 51 ll a2 = s2[n]-2*s2[i]; 52 ll s = c-a2; //a1*x=s 53 if(a1==0&&s==0){ 54 flag = 1; 55 break; 56 } 57 else if(a1==0){ 58 continue; 59 } 60 else { 61 ll num1 = abs(s); 62 ll num2 = abs(a1); 63 ll gcd = __gcd(num1,num2); 64 double ss = (double)s/a1; 65 if((i==n||ss>g[i+1].s)&&(i==0||ss<=g[i].s)){ 66 if(ma[ss]==0){ 67 ma[ss]++; 68 v[cnt].x = s/gcd; 69 v[cnt].y = a1/gcd; 70 v[cnt].s = ss; 71 cnt++; 72 } 73 } 74 } 75 } 76 if(flag==1){ 77 cout<<-1<<endl; 78 } 79 else{ 80 cout<<cnt; 81 sort(v,v+cnt,cmp1); 82 for(ll i=0;i<cnt;i++){ 83 if(v[i].x*v[i].y>0){ 84 cout<<' '<<abs(v[i].x)<<'/'<<abs(v[i].y); 85 } 86 else if(v[i].x*v[i].y==0){ 87 cout<<' '<<"0/1"; 88 } 89 else { 90 cout<<" -"<<abs(v[i].x)<<'/'<<abs(v[i].y); 91 } 92 } 93 cout<<endl; 94 } 95 } 96 return 0; 97 }