比赛链接:这里写链接内容
A 斐波那契
链接:https://www.nowcoder.com/acm/contest/181/A
来源:牛客网
设f[i]表示斐波那契数论的第i项
f[1]=1,f[2] =1,f[i] = f[i - 1] + f[i - 2]
给定一个n
求
附题解
#include<iostream>
#include<cstdio>
using namespace std;
int main(){
string str;
cin>>str;
int len=str.length();
if((str[len-1]-'0')%2==0){
printf("1\n");
}
else{
printf("-1\n");
}
}
B 就不放了
C 序列
链接:https://www.nowcoder.com/acm/contest/181/C
来源:牛客网
小a有n个数,他想把他们划分为连续的权值相等的k段,但他不知道这是否可行。
每个数都必须被划分
这个问题对他来说太难了,于是他把这个问题丢给了你。
暴力可过,就是首先要满足的要求肯定是总和sum%k是否等于0,然后暴力枚举,有k个就行(在总和是k的倍数的情况下)
k = 0;
for(int j = 1; j <= N; j++) {
cur += a[j];
if(cur == sum / i) cur=0,k++;
}
ans[i] = (k == i);
但是二分的方法更有前途(蒟蒻拙见,大佬见谅呜呜呜)
这里贴一位大佬(牛客网流木)的二分(老实说我写二分真要命)
#include<bits/stdc++.h>
const int M=1000005;
typedef long long ll;
using namespace std;
ll a[M];
int n,q;
int main(){
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]),a[i]+=a[i-1];
while(q--){
ll x;
scanf("%lld",&x);
if(a[n]%x)puts("No");
else{
int f=1;
for(int i=1;i<=x-1;i++){
int w=lower_bound(a+1,a+n+1,i*a[n]/x)-a;
if(a[w]!=i*a[n]/x){f=0;puts("No");break;}
}
if(f)puts("Yes");
}
}
return 0;
}
D 小叶的巡查
就是一道树的直径题,开始把树的直径看错了,没敢写,what
树的直径就是双重dfs ,这题小心数据int会爆掉
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int MAXN=100001;
struct node{
int to,next,w;
}edge[MAXN];
int head[MAXN];
int num;
int n,m;
typedef long long ll;
void add_edge(int u,int v,int w){
edge[++num].next=head[u];
edge[num].to=v;
edge[num].w=w;
head[u]=num;
}
int dp[MAXN];
ll ans=0;
int ed=0;
void dfs(int u,int fa,ll now)
{
if(now>ans)
{
ans=now;
ed=u;
}
for(int i=head[u];i!=-1;i=edge[i].next)
{
if(edge[i].to!=fa)
dfs(edge[i].to,u,now+edge[i].w);
}
}
int main(){
scanf("%d",&n);
memset(head,-1,sizeof(head));
for(int i=1;i<n;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add_edge(u,v,w);
add_edge(v,u,w);
}
dfs(1,0,0);
dfs(ed,0,0);
printf("%lld",ans*10+(1+ans)*ans/2);
return 0;
}
E 旅行青蛙
就是一道最长不下降子序列的裸题
开始我写的是最长上升子序列,没看清题目,纳尼。
#include<iostream>
#include<cstdio>
using namespace std;
const int N=23333+10;
int dp[N],a[N];
int binarysearch(int k,int len){
int l=0,r=len-1;
while(l<=r) {
int mid=(l+r)>>1;
if(k<dp[mid]) {
r=mid-1;
} else {
l=mid+1;
}
}
return l;
}
int main() {
int n,len;
scanf("%d",&n);
for(int i=0; i<n; i++) {
scanf("%d",&a[i]);
}
len=0;
for(int i=0;i<n;i++){
int t=binarysearch(a[i],len);
if(t>=len) len++;
dp[t]=a[i];
}
printf("%d\n",len);
}
测试赛果然良心,除了F题,其他的都一眼可以看出解法,嗯,(敲码另说)呜呜呜呜
最后一题放一下题解,和大佬的代码记录一下吧,
贴的是牛客网applese大佬的代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
bool Finish_read;
template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;}
template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x%10+'0');}
template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('\n');}
template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);}
/*================Header Template==============*/
const int mod=1e9+7;
namespace {
inline int Add(const int &x,const int &y,const int &p) {
int res=x+y;
if(res>=p)
res-=p;
return res;
}
inline int Sub(const int &x,const int &y,const int &p) {
int res=x-y;
if(res<0)
res+=p;
return res;
}
inline int Mul(const int &x,const int &y,const int &p) {
return 1ll*x*y%p;
}
inline int Pow(int x,int y,const int &p) {
int res=1;
while(y) {
if(y&1)
res=1ll*res*x%p;
x=1ll*x*x%p;
y>>=1;
}
return res;
}
}
int T,n,k,val[1005],C[1005][1005];
int main() {
for(int i=0;i<=1000;++i) {
C[i][0]=1;
for(int j=1;j<=i;++j)
C[i][j]=Add(C[i-1][j-1],C[i-1][j],mod-1);
}
read(T);
while(T--) {
read(n),read(k);
for(int i=1;i<=n;++i)
read(val[i]);
if(k<=2) {
puts("1");
continue;
}
sort(val+1,val+n+1);
int ans=1;
for(int i=1;i<=n;++i)
ans=Mul(ans,Pow(val[i],Sub(C[n-1][k-1],Add(C[i-1][k-1],C[n-i][k-1],mod-1),mod-1),mod),mod);
printf("%d\n",ans);
}
}