hihocoder 挑战赛后学习 #1245 #1246

来源:互联网 发布:java中构造器 编辑:程序博客网 时间:2024/06/05 08:25

#1245

同周长等边三角形面积最大,尽量把三边拉成等边:

#include<iostream>  #include<map>#include<string>   #include<algorithm>  #include<fstream>#include<cmath>  #include<vector>#include<queue>#include<map>#include<math.h>using namespace std;  #define lch(i) ((i)<<1)  #define rch(i) ((i)<<1|1)  #define sqr(i) ((i)*(i))  #define pii pair<int,int>  #define mp make_pair  #define FOR(i,b,e) for(int i=b;i<=e;i++)  #define FORE(i,b,e) for(int i=b;i>=e;i--)  #define ms(a)   memset(a,0,sizeof(a))  const int maxnum =2005;const int mod = 1000000007;int n,m,len,deepest;int num[maxnum];int com[50000005];double a,b,c,l;double ma,mb;double cal(double pa,double pb,double pc){double s = (pa+pb+pc)/2;return sqrt(s*(s-pa)*(s-pb)*(s-pc));}int main()    {  int t;cin>>t;while(t--){cin>>a>>b>>c>>l;if(a>b)swap(a,b);if(a>c)swap(a,c);if(b>c)swap(b,c);double k=l>b-a?b-a:l;a+=k,l-=k;k=l>(c-b)*2?(c-b)*2:l;a+=k/2,b+=k/2,l-=k;a+=l/3;b+=l/3;c+=l/3;printf("%.10lf\n",cal(a,b,c));}return 0;}  
#1246

解题报告提示了该公约数必定是总和的公约数。先缩小范围。

sum[i]表示从1~i的数的和

sum[i]%divisor相同的两个数之间的和能整除divisor,又因为总和能整除divisor 所以剩下的数的和也能整除divisor

求出能划分出最多的能整除divisor的区间数num,因为区间可以合并,所以区间数从1到num的公约数都可以取divisor,然后求出最大

#include<iostream>  #include<map>#include<string.h>   #include<algorithm>  #include<fstream>#include<cmath>  #include<vector>#include<queue>#include<map>#include<math.h>using namespace std;  #define lch(i) ((i)<<1)  #define rch(i) ((i)<<1|1)  #define sqr(i) ((i)*(i))  #define pii pair<int,int>  #define mp make_pair  #define FOR(i,b,e) for(int i=b;i<=e;i++)  #define FORE(i,b,e) for(int i=b;i>=e;i--)  #define ms(a)   memset(a,0,sizeof(a))  const int maxnum =2005;const  int  mod = 10007;int n,m,len,deepest;long long sum[maxnum], choose[maxnum],mo[maxnum];map <long long,int> mapLLI;void check(long long divisor){int times=0;FOR(i,1,n){mo[i] = sum[i]%divisor;}mapLLI.clear();int sm = 1;FOR(i,1,n){if(mapLLI[mo[i]]){mapLLI[mo[i]]++;sm = max(mapLLI[mo[i]],sm);}elsemapLLI[mo[i]]=1;}FOR(i,1,sm){if(choose[i]<divisor)choose[i]=divisor;}}int main()    {  cin>>n;sum[0]=0;ms(choose);FOR(i,1,n){scanf("%d",&sum[i]);sum[i]+=sum[i-1];}for(int i=1;(long long)i*i<=sum[n];i++){if(sum[n]%i==0){check(i);check(sum[n]/i);}}FOR(i,1,n){printf("%lld\n",choose[i]);}return 0;}  



0 0
原创粉丝点击