2020上海站补题记录
G—Fibonacci
问斐波那契数列前n项中,有几对数的乘积是偶数。
斐波那契数列前两项是奇数,奇加奇等于偶,所以偶数隔三个出现一次,我们如果直接算每个数对答案的贡献,需要分偶数和奇数考虑,比较繁琐,所以我们可以考虑先把所有数对记上,再减去数对积不为奇数的个数就是答案。
所以只需要算一下奇数的个数;
#include<iostream>
using namespace std;
int main()
{
long long n,m;
cin>>n;
m=(n/3)*2+n%3;
cout<<n*(n-1)/2-m*(m-1)/2<<endl;
}
M-Gitignore
(思维,模拟)
给你一堆目录,需要删除一部分文件,需要保留一部分文件,如果一个文件夹里的文件全部都能删除,那就可以直接删除这个文件夹,问你删除所有需要删除的文件最少需要删除多少个文件。
先考虑如何存储目录,我们判断一个文件夹能不能删掉,主要要看这个文件夹里的所有文件有没有不能删的,所以我们把不能删目录记录下来,在遍历需要删的目录,只要需要删的目录被记录过了,就得一个一个删,所以我们可以用map来存储所有目录
如果map[s]=1说明该目录不能删
如果map[s]=0说明该目录需要删,删除后将该目录记为2,表示已经删过了
如果map[s]=2说明该目录已经删过了,而现在在删过的目录下又有一个要删的文件,那么就让ans–,说明不需要单独删这个目录,因为之前已经删过了。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3+10;
string s1[N],s2[N];
map<string,int>q;
int main()
{
int tt;
cin>>tt;
while(tt--){
q.clear();
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>s1[i];
for(int i=1;i<=m;i++)
cin>>s2[i];
for(int i=1;i<=m;i++)
{
int l=s2[i].size();
string t="";
for(int j=0;j<l;j++)
{
t+=s2[i][j];
if(s2[i][j]=='/')
q[t]=1;
}
}
int ans=n;
for(int i=1;i<=n;i++)
{
int l=s1[i].size();
string t="";
for(int j=0;j<l;j++)
{
t+=s1[i][j];
if(s1[i][j]=='/')
{
if(q[t]==0)
q[t]=2;
else if(q[t]==2)
{
ans--;
break;
}
}
}
}
cout<<ans<<endl;
}
}
b题
给你两个扫雷图AB,你可以反转B的地雷或者空地属性最多[n*m/2]次,使得AB的空地上的数字和相同。
核心:要想到将一个扫雷图中的空地和地雷属性反转,空地上的数字和不变。
先记录下AB中不同的个数cnt 如果cnt<=[n*m/2]直接将B变成A即可,如果cnt>[n * m/2],就将A反转,因为反转后cnt一定小于[n * m/2]