10.03 T1 数学
1、宝石(gem)
题目描述:
现在小H手上有一堆宝石,每个宝石有一个幸运度。他可以把两个宝石融合在一起。融合的时候要区分主系和副系。具体来说,如果我们用i号宝石作为主系,j号宝石作为副系,则新宝石的幸运度就是。反过来,j号宝石作为主系,i号宝石作为副系,则新宝石的幸运度就是。
小H想要知道前K大的融合方案。对于每种方案,你只需要输出主系宝石的幸运度与副系宝石的幸运度。
注意:小H不喜欢4和2,所以拥有这两种幸运度的宝石不会同时出现。你必须将两个不同的宝石融合在一起,但是这两个宝石的幸运度是可以相同的。
输入格式:
第一行两个正整数n,k;
接下来n个数。
输出格式:
K行,每行两个用空格隔开的整数。,意义如题目描述。
样例输入1:
2 2
2 3
样例输入2:
10 5
6 5 15 4 13 3 16 8 11 9
样例输出1:
3 2
2 3
样例输出2:
15 16
16 15
13 16
13 15
11 16
数据规模与约定:
40分:暴力/高精度
code:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<string> 5 #include<cstring> 6 #define N 160000 7 using namespace std; 8 struct node{ 9 int a,b; 10 char v[2005]; 11 }e[N]; 12 bool cmp(int a,int b){ 13 return a>b; 14 } 15 int a[100005]; 16 bool bmp(node a,node b){ 17 if(strlen(a.v)>strlen(b.v))return 1; 18 else if(strlen(a.v)<strlen(b.v))return 0; 19 for(int i=0;i<strlen(a.v);i++){ 20 if(a.v[i]>b.v[i])return 1; 21 if(a.v[i]<b.v[i])return 0; 22 } 23 return 1; 24 } 25 void High_Char(char a[], char b[]) { 26 int num[500]; 27 memset(num, 0, sizeof(num)); 28 int l = strlen(a) + strlen(b); 29 int la = strlen(a); 30 int lb = strlen(b); 31 int sum; 32 for(int i=lb-1; i>=0; --i) { 33 for(int j=la-1,k=i+j+1; j>=0; --j,--k) { 34 sum = (b[i]-'0') * (a[j]-'0') + num[k]; 35 num[k] = sum%10; 36 num[k-1] += sum/10; 37 } 38 } 39 int i=num[0]?0:1; 40 for(int j=0; i<l; i++) { 41 a[j++] = (num[i]+'0'); 42 a[j] = 0; 43 } 44 } 45 int main(){ 46 freopen("gem.in","r",stdin); 47 freopen("gem.out","w",stdout); 48 // cout<<G_cheng("340","40"); 49 int n,k; 50 cin>>n>>k; 51 for(int i=1;i<=n;i++)cin>>a[i]; 52 sort(a+1,a+n+1,cmp); 53 int tot=0; 54 for(int i=1;i<=n;i++){ 55 for(int j=1;j<=n;j++){ 56 if(i==j||(a[i]==2&&a[j]==4)||(a[i]==4&&a[j]==2))continue; 57 e[++tot].a=a[i],e[tot].b=a[j]; 58 char g[100005],h[100005]; 59 sprintf(g,"%d",a[i]); 60 sprintf(h,"%d",a[i]); 61 // cout<<g[0]<<endl; 62 // sprintf(h,"%d",j); 63 for(int k=1;k<a[j];k++){ 64 High_Char(g,h); 65 } 66 for(int i=0;i<strlen(g);i++)e[tot].v[i]=g[i]; 67 } 68 } 69 sort(e+1,e+tot+1,bmp); 70 for(int i=1;i<=k;i++){ 71 cout<<e[i].a<<" "<<e[i].b<<'\n'; 72 } 73 return 0; 74 }
100分:
显然太大,要用高精度一些技巧来处理。
考虑取对数:,log是递增的函数,所以可以用取对数过后的结果来进行比较。
code:
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #define N 1000005 6 using namespace std; 7 struct node{ 8 int a,b; 9 double v; 10 }e[N]; 11 int a[30000]; 12 double b[30005]; 13 int tot; 14 bool cmp(node a,node b){ 15 return a.v>b.v; 16 } 17 int main(){ 18 freopen("gem.in","r",stdin); 19 freopen("gem.out","w",stdout); 20 int n,k; 21 cin>>n>>k; 22 for(int i=1;i<=n;i++){ 23 cin>>a[i]; 24 b[i]=log2(a[i]); 25 } 26 for(int i=1;i<=n;i++){ 27 for(int j=1;j<=n;j++){ 28 if(i==j||(a[i]==2&&a[j]==4)||(a[i]==4&&a[j]==2))continue; 29 e[++tot].a=a[i],e[tot].b=a[j],e[tot].v=1.0*a[j]*b[i]; 30 } 31 } 32 sort(e+1,e+tot+1,cmp); 33 for(int i=1;i<=k;i++) 34 cout<<e[i].a<<" "<<e[i].b<<'\n'; 35 return 0; 36 }
over