Codeforces Round #320 (Div. 2)

B.http://codeforces.com/contest/579/problem/B

题意:有n个队,2n个人,接着2n-1行,第i行(在输入中为i+1行)表示第j列表示第i个人和第j个人组队所能得到的分数,每个人都想自己的分数尽可能的高,输出每个人和谁组队

分析:将输入存入结构体中,结构体含变量x,y,d,x和y表示组队的两个人,d表示组队得到的分数,按分数从大到小进行排序,不断确定组队情况

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 using namespace std;
 6 const int maxn=810;
 7 struct node{
 8     int x,y,d;
 9 }arr[maxn*maxn];
10 int belong[maxn];
11 
12 bool cmp(node a,node b)
13 {
14     return a.d>b.d;
15 }
16 
17 int main()
18 {
19     int i,j,k,n,cnt;
20     while ( scanf("%d",&n)!=EOF )
21     {
22         memset(belong,0,sizeof(belong));
23         cnt=0;
24         for ( i=2;i<=2*n;i++ )
25             for ( j=1;j<i;j++ )
26             {
27                 scanf("%d",&arr[++cnt].d);
28                 arr[cnt].x=i;
29                 arr[cnt].y=j;
30             }
31         sort(arr+1,arr+1+cnt,cmp);
32         for ( i=1;i<=cnt;i++ )
33         {
34             if ( belong[arr[i].x] || belong[arr[i].y] ) continue;
35             else {
36                 belong[arr[i].x]=arr[i].y;
37                 belong[arr[i].y]=arr[i].x;
38             }
39         }
40         for ( i=1;i<=2*n;i++ )
41         {
42             printf("%d",belong[i]);
43             if ( i!=2*n ) printf(" ");
44             else printf("\n");
45         }
46     }
47     return 0;
48 }
579B

C.http://codeforces.com/contest/579/problem/C

题意:给出一条过点(0, 0) – (x, x) – (2x, 0) – (3x, x) – (4x, 0) – ... - (2kx, 0) – (2kx + x, x) – ....的折线,再给出点(a,b),问经过点(a,b)的折线中,x最小是多少?如果没有折线经过(a, b)则输出-1。答案精确到小数点后9位。

分析:数学。根据题意可得图中所有直线的斜率都为1或-1。而当(a,b)在k=1的直线上时,(a,b)前一个点为(a-b,0);当(a,b)在k=-1的直线上时,(a,b)后一个点为(a+b,0)。因为a+b和a-b的奇偶性相同,选择一个考虑就行。我们考虑(a+b,0)这个点,假设[0,a+b]中一共有2p个x,那么我们有x=(a+b)/2p&&x>=b,结合两条式子可以先求得最大的p进而推得x。注意特判b/a>1的情况是不存在解的,输出-1

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 using namespace std;
 6 const double eps=1e-9;
 7 
 8 int main()
 9 {
10     int a,b,i,j,x1,x2,p;
11     double k,ans,l,r,mid;
12     while ( scanf("%d%d",&a,&b)!=EOF )
13     {
14         k=(double)1.0*b/a;
15         if ( k-1>eps )
16         {
17             printf("-1\n");
18             continue;
19         }
20         x1=a-b;
21         x2=a+b;
22         p=x2/(2*b);
23         ans=(double)(1.0*x2/(2*p));
24         printf("%.9lf\n",ans);
25     }
26     return 0;
27 }
579C

D.http://codeforces.com/contest/579/problem/D

题意:给出n个数,有最多k次操作,每次操作可以使得一个数乘x,最后将n个数进行或操作取和,求最大的和是多少

分析:因为是or操作,所以要使最高位尽可能的高,所以将k次乘法操作都进行在一个数上。所以枚举每个数进行k次操作,此时有个技巧:即维护前后缀的或和,这样可以方便计算

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 using namespace std;
 6 typedef long long ll;
 7 const int maxn=2e5+10;
 8 ll a[maxn],b[maxn],c[maxn];
 9 
10 int main()
11 {
12     ll n,k,x,i,j,ans,now,add;
13     while ( scanf("%lld%lld%lld",&n,&k,&x)!=EOF )
14     {
15         add=pow(x,k);
16         memset(a,0,sizeof(a));
17         memset(b,0,sizeof(b));
18         for ( i=1;i<=n;i++ ) 
19         {
20             scanf("%lld",&c[i]);
21             a[i]=a[i-1]|c[i];
22         }
23         for ( i=n;i>0;i-- ) b[i]=b[i+1]|c[i];
24         ans=0;
25         for ( i=1;i<=n;i++ )
26         {
27             now=(c[i]*add)|a[i-1]|b[i+1];
28             ans=max(ans,now);
29         }
30         printf("%lld\n",ans);
31     }
32     return 0;
33 }
579D

猜你喜欢

转载自www.cnblogs.com/HDUjackyan/p/9063722.html