codeforces #382 题解 735ABCD
这场是个数学专场,基本靠手速,很后悔没打,从C题还是看到了自己的不足,对数学不够敏感,不会猜
A题样例出得够好了:两个判断条件:起点和终点的差值的绝对值是否能被k整除,从起点到终点的路上不能碰到障碍物#号
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=150;
int n,k;
int st,ed;
char s[maxn];
bool ok(){
if ((ed-st)%k) return false;
for(int i=st+k;i<ed;i+=k)
if (s[i]=='#') return false;
return true;
}
int main(){
while(scanf("%d%d",&n,&k)!=EOF){
scanf("%s",s);
for(int i=0;i<n;i++)
if (s[i]=='G') st=i;
else if (s[i]=='T') ed=i;
if (st>ed) swap(st,ed);
if (ok()) puts("YES");
else puts("NO");
}
return 0;
}
B题:是个排序题:记得比较n1和n2的大小,因为最大的前几个数放到数字少的集合里面才是最赚的(贪心思想),排序后,累加就好
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+50;
int n,n1,n2;
int a[maxn];
double ans;
int main(){
while(scanf("%d",&n)!=EOF){
scanf("%d%d",&n1,&n2);
if (n1>n2) swap(n1,n2);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
sort(a+1,a+n+1);
ans=0;
for(int i=n-n1+1;i<=n;i++)
ans+=a[i]*1.0/n1;
for(int i=n-n1-n2+1;i<=n-n1;i++)
ans+=a[i]*1.0/n2;
printf("%.8lf\n",ans);
}
return 0;
}
C题:要好好分析一下了:题目中很重要的一句话
two players can play against each other only if the number of games one of them has already played differs by no more than one from the number of games the other one has already played.
注意:no more than one:也就是图中提示的深色字体部分
小数据来打表:我们只要判断什么时候可以增长就好
n=2,ans=1
n=3,ans=2(ABC三个人打比赛)
n=5,ans=3(ABC三个人打比赛,选出1人;DE两个人打比赛选出1人)
n=8,ans=4(ABCDE五个人打比赛,选出1人;FGH三个人打比赛选出1人)
……
看出来什么了吗?fib数列:打表一发!!!(赛后补题才会的,确实脑洞和数学思维还不够)
#include<bits/stdc++.h>
using namespace std;
#define LL __int64
const int maxn=500;
LL ans[maxn],n;
int main(){
ans[0]=1;
ans[1]=2;
for(int i=2;;i++){
ans[i]=ans[i-1]+ans[i-2];
if (ans[i]>1e18) break;
}
while(cin>>n){
for(int i=1;;i++)
if (ans[i]>n){
printf("%d\n",i-1);
break;
}
}
return 0;
}
D题:数论简单题
在小数据范围内:是证明过歌德巴赫猜想的:即:任何一个偶数能被分解成两个不同的奇数素数之和
那么根据题意:我们只需要对素数和奇数进行分类就好:
如果是素数,那么答案是1
如果不是素数,是偶数:那么答案是2(根据歌德巴赫猜想,在小数据是成立的)
如果不是素数,是奇数:
这个时候要分两类:
第一类:拿走3,剩下一个偶数:答案是3
第二类:拿走2,剩下一个奇数(因为这个奇数可能会是素数),答案可能是2,所以判断一下就好
这个题跟C一样是个脑洞题:只能说明自己数论这些结论知道的多一点熟悉一点,组合数学不太熟悉,需要加油
#include<bits/stdc++.h>
using namespace std;
int n;
bool isprime(int x){
for(int i=2;i*i<=x;i++)
if (x%i==0) return false;
return true;
}
int main(){
while(scanf("%d",&n)!=EOF){
if (isprime(n)) puts("1");
else if (n%2){
if (isprime(n-2)) puts("2");
else puts("3");
}
else puts("2");
}
return 0;
}