题目链接
Codeforces Round #580 (Div. 2)
A
思路
直接暴力查询或者直接输出两个最大的即可
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
   | #include<bits/stdc++.h> using namespace std; #define ll long long const int maxn = 250; int a[250],b[250]; bool vis[maxn*2]; int main() { 	int n,m; 	scanf("%d",&n); 	for(int i=0;i<n;i++) 	{ 		scanf("%d",&a[i]); 		vis[a[i]]=true; 	} 	cin>>m; 	for(int i=0;i<m;i++) 	{ 		scanf("%d",&b[i]); 		vis[b[i]]=true; 	} 	int ans1=0,ans2=0; 	for(int i=0;i<n;i++) 	{   bool ok =false; 		for(int j=0;j<m;j++) 		{ 			if(!vis[a[i]+b[j]]) 			{ 				printf("%d %d\n",a[i],b[j]); 				ok=true; 				break; 			} 		} 		if(ok)break; 	} 	return 0; }
   | 
 
B
思路
首先把负数变为-1,正数和0变为1,先统计一遍答案,最后如果负数的个数不为偶数并且0的个数为0,那么需要从1变成-1,如果0的个数不为0,那么0变成1和变成-1的贡献是一样的。
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
   | #include<bits/stdc++.h> using namespace std; const int maxn = 1e5+10; long long a[maxn]; int main() { 	int n; 	scanf("%d",&n); 	for(int i=0;i<n;i++)scanf("%I64d",&a[i]); 	int num0=0,num1=0; 	int zero=0; 	long long maxx = -1000000001; 	long long minn = 1000000001; 	long long ans = 0; 	for(int i=0;i<n;i++) 	{ 		if(a[i]>0) 		{ 			num1++; 			minn=min(a[i],minn); 		} 		else if(a[i]<0) 		{ 			num0++; 			maxx=max(maxx,a[i]); 		} 		else  		{ 			zero++; 		} 	} 	for(int i=0;i<n;i++) 	{ 		if(a[i]>0)ans+=(a[i]-1); 		else if(a[i]<0)ans+=(-1-a[i]); 		else if(a[i]==0)ans++; 	} 	if(num0%2==1&&!zero) 	{ 		ans+=2; 	} 	cout<<ans<<endl; }
   | 
 
C
思路
想着最优构造,使得左右两半的差值最小,现在左边放1,右边23,左边45,右边67,以此类推。
发现偶数无解。
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
   | #include<bits/stdc++.h> using namespace std; const int maxn=4e5+10; int a[maxn]; int b[maxn*2]; int n; int main() { 	scanf("%d",&n); 	int cnt =1; 	bool ok = false; 	for(int i=0;i<n;i++) 	{   if(!ok) 		{ 			a[i]=cnt++; 		a[i+n]=cnt++; 		ok=true; 		} 		else  		{ 			a[i+n]=cnt++; 			a[i]=cnt++; 			ok=false; 		} 	} 	int sum = 0; 	if(n%2==1) 	{   printf("YES\n"); 		for(int i=0;i<2*n;i++)printf("%d ",a[i]); 	} 	else printf("NO\n");  }
   | 
 
D
思路
首先若非0个数>128那么一定为3,因为最多64位,只要有一列上有3个3,那么输出3即可。
根据鸽巢原理,假设128个数中每一列只有2个1,那么任意多一个非零数,他就会有3个1.
所以,我们实际找的最小环的n大小只有150左右。用floyd判最小环即可。
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
   | #include<bits/stdc++.h> using namespace std; #define ll long long const int maxn = 1e5+10; ll a[maxn]; int mp[250][250]; int dis[250][250]; int res=99999999; int n; void floyd() {    	for(int k=0;k<n;k++) 	{ 		for(int i=0;i<k;i++) 		{ 			for(int j=i+1;j<k;j++) 			{ 				res=min(res,dis[i][j]+mp[j][k]+mp[k][i]); 			} 		} 		for(int i=0;i<n;i++) 		{ 			for(int j=0;j<n;j++) 			{ 				dis[i][j]=dis[j][i]=min(dis[i][j],dis[i][k]+dis[k][j]); 			} 		} 	} } int main() {     scanf("%d",&n); 	int num = 0; 	for(int i=0;i<n;i++)	 	{   long long tot; 		scanf("%I64d",&tot); 		if(tot!=0) 		{ 			a[num]=tot; 			num++; 		} 	} 	if(num>=200)return 0*printf("3\n"); 	n=num;     for(int i=0;i<n;i++)     for(int j=0;j<n;j++)     {     	mp[i][j]=mp[j][i]=10000000;     	dis[i][j]=dis[j][i]=10000000; 	} 	for(int i=0;i<n;i++) 	{  		for(int j=i+1;j<n;j++){ 			if(i!=j&&(a[i]&a[j])>0) 			{ 				mp[i][j]=mp[j][i]=1; 				dis[i][j]=dis[j][i]=1; 			} 		} 	} 	for(int i=0;i<n;i++)dis[i][i]=mp[i][i]=0; 	floyd(); 	if(res>100000)cout<<"-1"<<endl; 	else cout<<res<<endl; }
   |