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

 

posted @ 2018-10-03 14:35  saionjisekai  阅读(48)  评论(0编辑  收藏  举报