2021.10.18-2021.10.24(2)
1,A. Computer Game-Educational Codeforces Round 115 (Rated for Div. 2)
题意:有一个2*n的长方形,有字符1和0组成。开始在(1,1)最后要到(2,n)。只能走0不能走1,
而且x,y坐标每次各自最多增加一。问是否可以完成。
题解,(1)上下相或(先转为整数),为1就可以走到下一列。(2)判断如果下一列是否全为零。
#include<iostream>
#include<string>
using namespace std;
int n,m;
int i1,i2,i3,i4,i5;
string x,y;
int main()
{
int t;
cin >> t;
while(t--)
{
cin>>n;
cin >> x;
cin >> y;
for(i1=0;i1<n;i1++)
if(x[i1]=='1'&&y[i1]=='1') {cout<<"NO"<<endl;goto L;}
cout << "YES" << endl;
L:;
}
return 0;
}
2,B. Groups-Educational Codeforces Round 115 (Rated for Div. 2)
题意,有n个学生,给出每个学生周一到周五的的课程情况,要求找出两天,把n个学生分成2组,使得两组人数相同,并且两组人数在各自属于的两天中都有空。
题解:(1)每两天进行比较。p是只有第一天有课,第二天没课,q相反,m是都有课。第一步,n-m==p+q判断是否这两天包括所有人。第二步,temp=max(p,q)-min(p,q);m=m-temp;判断m%2来确定可以分配到这两天。
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int a[6][1010];
int n,m,k,p,q;
int i1,i2,i3,i4,i5;
int main()
{
int t;
cin >> t;
while(t--)
{
memset(a,0,sizeof(a));
cin >> n;
for(i1=1;i1<=n;i1++)
for(i2=1;i2<=5;i2++)
cin >> a[i2][i1];
for(i1=1;i1<=4;i1++)
{
for(i2=i1+1;i2<=5;i2++)
{
m=0;p=0;q=0;
for(i3=1;i3<=n;i3++)
{
if(a[i1][i3]==0&&a[i2][i3]==0){ p=99;q=1;break;}
if(a[i1][i3]==0&&a[i2][i3]==1) {q++;}
if(a[i1][i3]==1&&a[i2][i3]==0) {p++;}
if(a[i1][i3]==1&&a[i2][i3]==1) {m++;}
}
if(n-m!=p+q) continue;
int temp=max(p,q)-min(p,q);
m=m-temp;
if(m<0) continue;
if(m%2==0) {cout<<"YES"<<endl;goto L;}
}
}
cout << "NO" << endl;
L:;
}
return 0;
}
(2)也可以转换成二进制然后按位或操作,判断都为一的时候时候可以被二整除。留给同学们了。
总结,(1这题难在利用了行列转换,平时都是按行后列,现在是围绕列进行计算。(2)开始会想把每天的人数加起来,但no influence。
虽然是B题,但花费快2h。
3.C. Delete Two Elements-Codeforces Round 115 (Rated for Div. 2)
题意:有n个数,平均数是k,要求去掉两个元素后平均值也是k。(不是两个数,而是二个位置算一种情况,也就是多个重复的元素,但是位置不同算多重情况)
题解:(1)将平均值算出,然后k=平均值乘2。从第一个元素开始判断k-a[i]出现了几次(当k-a[i]==a[i]特殊)3,最后除以2。
#include<iostream>
#include<map>
#include<cstdio>
using namespace std;
int n,m;
int i1,i2,i3,i4,i5,i6;
map<double,int> it;
int a[200010];
int main()
{
int t;
cin >> t;
while(t--)
{
cin >> n;
it.clear();
long long sum=0;
for(i1=1;i1<=n;i1++)
{
scanf("%d",&a[i1]);
it[a[i1]]++;
sum+=a[i1];
}
double sum1=sum*1.0/n,sum2;
sum2=sum1*2;//cout <<sum2<< endl;
sum=0;
for(i1=1;i1<=n;i1++)
{
if(a[i1]*2.0==sum2) sum+=it[a[i1]]-1;
else sum+=it[sum2-a[i1]];
}
cout <<sum/2 << endl;
}
return 0;
}
解释:1,红糖水原理:当两杯不同容积但是相同浓度的水倒在一起时浓度不变。所以将大问题转换为了只算两个元素的小问题(2)解题中将相同的两个位置计算了两次,所以除以2。
总结(1)刚开始看到10e9和二分dp感觉很难,但是看只有1200分,觉得可能做不出来了,不过最后想了想没那么难。(2)解开这题离不开数学(=_=)。