Codeforces Round #320 (Div. 2)
Posted hdujackyan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }
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 }
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 }
以上是关于Codeforces Round #320 (Div. 2)的主要内容,如果未能解决你的问题,请参考以下文章
[ACM]Codeforces Round #534 (Div. 2)
Codeforces Round #726 (Div. 2) B. Bad Boy(贪心)
Codeforces 578B Or Game (前缀和 + 贪心)