G 题目链接:Problem - G - Codeforces
input1:
3
output1:
2
input2:
10
output2:
24
input3:
100
output3:
2739
题意:
给定一个数 n ,问斐波那契数列前 n 项任取两项,相乘等于偶数的情况有几种。
思路:
签到题。
显而易见的结论: 奇数相乘等于奇数,其他情况得到的都是偶数。
所以我们只需要用组合数解决问题。答案就是n个数任取两个的情况减去n个数中的奇数任取两个的情况。具体公式见代码。
代码如下:
#include<bits/stdc++.h>
#define endl "\n"
using namespace std;
typedef long long ll;
ll n;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
cout<<(n-1)*n/2-(n-n/3-1)*(n-n/3)/2<<endl;
return 0;
}
B 题目链接:Problem - B - Codeforces
input:
2 4
X..X
X.X.
X.X.
.X..
output:
X.XX
.X..
题意:
给n*m个格子的扫雷地图A和图B,输入中‘X’代表地雷,‘.’代表没有地雷。对于每个无雷点,都可以计算一个数字,数字的含义为周围所有格子的地雷数量(包括对角的四个格子)。现有一种操作,可以令任一格子的状态相反(有雷变无雷,无雷变有雷),这种操作最多不超过 m*n/2 (下取整) 次。要求对图B经若干次操作后,使得图A所有无雷点数字的加和等于图B所有无雷点数字的加和。输出更改后的图B。
思路:
思维题。
首先,明显可以得出,我们只需要把图B变成完全和图A一样即可,但是存在一个问题,如果图A和图B差距大的话,m*n/2 (下取整) 次数不够用。
造了几个样例以后发现,有一个比较有趣的现象:当构造一个图,与原图完全相反时,得到的无雷点数字之和与原图竟然一样!(不知道如何用数学证明/(ㄒoㄒ)/~~)
所以直接比较图A和图B有几个点不同,小于m*n/2 (下取整)就直接输出图A,否则输出图A的反
代码如下:
#include<bits/stdc++.h>
#define endl "\n"
using namespace std;
const int N=1010;
char a[N][N],b[N][N];
int n,m;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
}
}
int cnt=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>b[i][j];
if(a[i][j]!=b[i][j])
++cnt;
}
}
if(cnt<=(n*m)/2)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cout<<a[i][j];
}
cout<<endl;
}
}
else
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i][j]=='.')
cout<<'X';
else
cout<<'.';
}
cout<<endl;
}
}
return 0;
}
D 题目链接:Problem - D - Codeforces
input:
2
10000.0 1.0 0.001 9999.0 0.001
4306.063 4079.874 0.607 1033.423 0.847
output:
5001000.0000000000
3827.8370013755
题意:
有一条长度为 n 的路,第一个人在位置 p1 ,速度为 v1 ,第二个人在位置 p2 ,速度为 v2 ,问两个人走的路径完全覆盖整条路的最短时间是多少(答案精度在1e-6以内即可)。
思路:
和队友分析了一通,最后将一堆情况整合成了三种情况。
情况一:其中某一个人速度巨快,直接一个人走完所有路。
情况二:两个人相向而行,分别走到路的两端。
情况三:以某一个中心点为界,两个人各走一段路(这个点一定在 p1 , p2 之间)。
三种情况取最优解即可。
情况一和二我们可以直接写出式子,对于情况三,我们需要讨论中心点在哪里。
对于情况三,我们的做法是直接三分求极值,结果也是对的(注意,三分时精度太高会超时!!训练后试代码发现了这个问题,训练中跟队友说开1e-12做,幸好后来改成了1e-8)。训练中队友提到两个人同时走完路程是最优的,这一点我没有加以利用。赛后也看了一下其他大佬的题解,发现他们利用这一点直接二分,让两个人的用时趋近平衡,最后得到答案。
我们的三分代码如下:
#include<bits/stdc++.h>
using namespace std;
double p1, p2, v1, v2;
double n;
double get(double x)
{
double x1=(x+min(p1,x-p1))/v1;
double x2=(n-x+min(p2-x,n-p2))/v2;
return max(x1,x2);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while(t--)
{
cin>>n>>p1>>v1>>p2>>v2;
if(p1>p2)
swap(p1,p2),swap(v1,v2);
double l=p1,r=p2;
double mid;
double ans = 1e18;
while(r-l>1e-8)
{
mid=(l+r)/2;
double mid1=(mid+l)/2;
ans=min(ans,get(mid));
ans=min(ans,get(mid1));
if(get(mid)>get(mid1))
{
r=mid;
}
else
{
l=mid1;
}
}
double sglTime=min((n+min(p1,n-p1))/v1,(n+min(p2,n-p2))/v2);
double dblTime=max((n-p1)/v1,p2/v2);
ans=min(ans,sglTime);
ans=min(ans,dblTime);
cout<<setprecision(20)<<ans<<endl;
}
}
M 题目链接:Problem - M - Codeforces
input:
2
3 0
data/train
data/test
model
3 1
data/train
data/test
model
data/sample
output:
2
3
题意:
现在有一个大文件夹,里面有一些文件和子文件夹,子文件夹里又有一些文件和子文件夹(文件夹都不是空的)。现在要将这些文件上传,但是有一些文件可以忽略,不用上传,有一些文件需要保护,一定要上传。每次忽略,我们可以忽略一个文件,或直接忽略一个文件夹的所有内容(包括所有文件和子文件夹),前提是里面不存在任何受保护的文件。另外,不能直接忽略这个大文件夹。现给出n个需要忽略文件的路径和m个受保护文件的路径,问最小要操作几次可以忽略掉所有指定文件。
思路:
对图没啥思路,这题基本是一窍不通,只是大概能想出来该怎么做却不会实现。这里贴一下队友的代码吧/(ㄒoㄒ)/~~
#include<bits/stdc++.h>
using namespace std;
const int MAXN=10001;
int T,n,k,num,ans;
struct node
{
string s;
bool f;
}a[MAXN];
vector<int> e[MAXN];
// 1 is keep
bool up(int u)
{
// cout<<"ss"<<a[u].s<<endl;
if(e[u].size() == 0 )
{
return a[u].f;
}
bool flag = 0;
for(int i = 0 ; i < e[u].size() ; i ++ ){
if( up(e[u][i]) == true ){
flag = true;
}
}
if(flag == false){
a[u].f = 0;
}else a[u].f = 1;
return a[u].f;
// cout << a[u].s << "|"<< ' ' << a[u].f << endl;
}
int down(int u){
if(a[u].f == 0) {
return 1;
}
int sum=0;
for(int i = 0 ; i < e[u].size() ; i ++ ){
sum+=down(e[u][i]);
}
// cout<<"now: "<<a[u].s<<" sum: "<<sum<<endl;
return sum;
}
void solve()
{
cin>>n>>k;
string s,t;
for(int i=1;i<=num;i++) a[i].f=0,e[i]=vector<int>();
num=1;ans = 0;
a[1].s="main";
for(int i=1;i<=n;i++)
{
cin>>s;
int pre=0,fa=1;
for(int j=0;j<s.length();j++)
{
if(s[j]=='/')
{
t=s.substr(pre,j-pre);
// cout<<t<<"/"<<endl;
pre=j+1;
bool f=0;
for(int u=0;u<e[fa].size();u++)
{
if(a[e[fa][u]].s==t)
{
f=1;
fa=e[fa][u];
break;
}
}
if(!f)
{
a[++num].s=t;
a[num].f=0;
e[fa].push_back(num);
fa=num;
}
}
}
t=s.substr(pre,s.length()-pre);
// cout<<t<<"/"<<endl;
a[++num].s=t;
e[fa].push_back(num);
a[num].f=0;
}
for(int i=1;i<=k;i++)
{
cin>>s;
int pre=0,fa=1;
for(int j=0;j<s.length();j++)
{
if(s[j]=='/')
{
t=s.substr(pre,j-pre);
// cout<<t<<endl;
pre=j+1;
bool f=0;
for(int u=0;u<e[fa].size();u++)
{
if(a[e[fa][u]].s==t)
{
f=1;
fa=e[fa][u];
break;
}
}
if(!f)
{
a[++num].s=t;
a[num].f=0;
e[fa].push_back(num);
fa=num;
}
}
}
t=s.substr(pre,s.length()-pre);
// cout<<t<<endl;
a[++num].s=t;
e[fa].push_back(num);
a[num].f=1;
}
up(1);
// down(1);
a[1].f=1;
cout << down(1) << endl;
}
int main(){
ios::sync_with_stdio(false);
int _ ; cin >> _;
while(_--)
{
solve();
}
}