由于想准备期末考试和四级 这星期没学多少,就是做了一点题,然而四级和期末考试也准备的不怎么样,简单来说这星期光睡懒觉了,,,真想给自己一巴掌,咋这么能睡呢,,,下星期要重新做人,不能再这样了
牛客 来点gcd
首先要作预处理,把从1到n的公约数能找的都找出来,对一个数判定序列里有没有这个数,只要找他的倍数来进行gcd就可以了
2021牛客月赛40 题解_ccsu_yuyuzi的博客-CSDN博客
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
const int mod=1e7;
int t,n,m,x,a[1000005],vis[1000005];
int main(){
//freopen("in.txt","r",stdin);
cin>>t;
while(t--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) a[i]=0,vis[i]=0;
for(int i=1;i<=n;i++){
scanf("%d",&x);
a[x]++;
}
for(int i=1;i<=n;i++)//保证从1到n都找一遍
for(int j=i;j<=n;j+=i)
if(a[j]){
vis[i]=__gcd(j,vis[i]);
}
for(int i=1;i<=m;i++){
scanf("%d",&x);
if(vis[x]==x)
printf("YES\n");
else printf("NO\n");
}
}
return 0;
}
牛客 跳跳跳
区间dp的一道很简单的题目,但我有一段时间没看加上刷的题目也少都忘却了
2021牛客月赛40 题解_ccsu_yuyuzi的博客-CSDN博客
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
const int mod=1e7;
int n,a[4005],dp[4005][4005];
int main(){
// freopen("in.txt","r",stdin);
cin>>n;
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++) {
scanf("%d",&a[i]),a[n+i]=a[i];
dp[i][i]=dp[i+n][i+n]=a[i];
}
int ans=0;
for(int len=1;len<=n;len++)//len的范围必须这样,不然下面的方程式就不对了
for(int i=1;i<=n+n-len+1;i++){
int j=i+len-1;
dp[i][j]=max(dp[i+1][j]+a[i]*len,dp[i][j-1]+a[j]*len);
ans=max(dp[i][j],ans);
//cout<<ans<<endl;
}
printf("%d",ans);
return 0;
}
牛客 小红的rpg游戏
一开始用bfs感觉不好记录状态,之后就用dfs写了一遍,果然超时。。。最后看了别人的代码才知道就是用bfs,不但要记录x,y,还要记录h,这样就能保证记录的状态不会重复;
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
int n,m,h,vis[55][55][55];
char s[55][55];
int dir[5][5]={
{-1,0},{1,0},{0,1},{0,-1},
};
struct xh{
int x,t,y,hp;
}fir,sec;
int main(){
// freopen("in.txt","r",stdin);
scanf("%d%d%d",&n,&m,&h);
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++) scanf("%s",s[i]+1);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(s[i][j]=='.') s[i][j]='0';
queue<xh>q;
while(!q.empty()) q.pop();
fir.x=1,fir.t=0,fir.y=1,fir.hp=h;vis[1][1][h]=1;
q.push(fir);
int ans=inf;
while(!q.empty()){
fir=q.front();q.pop();
if(fir.x==n&&fir.y==m&&fir.hp>0){ans=fir.t;break;}
if(fir.hp<=0) continue;
for(int i=0;i<4;i++){
int sx=fir.x+dir[i][0];
int sy=fir.y+dir[i][1];
if(sx<1||sy<1||sx>n||sy>n) continue;
if(s[sx][sy]!='*'&&fir.hp>s[sx][sy]-'0'&&!vis[sx][sy][fir.hp]){
sec.x=sx;sec.y=sy;sec.t=fir.t+1;
sec.hp=fir.hp-(s[sx][sy]-'0');
q.push(sec);vis[sx][sy][sec.hp]=1;
}
}
}
printf("%d\n",ans==inf?-1:ans);
return 0;
}
牛客 小红的数组
二分题,从i=1开始遍历,找到第一个大于等于k/a[i]数的下标和第一个大于k/a[i]数的下标,如果找不到说明与i搭配的数乘积都小于k,若找到则大于k的方案有ans1+=n-r+1,等于的有ans2=r-l,小于的有ans3=l-i-1;
牛客小Bai月赛41--小红的数组_Ghostttttttiii的博客-CSDN博客
#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<cstdio>
#include<iomanip>
#include<map>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
const int mod=1000000007;
ll n,k,a[300005],l,r;
int main(){
//freopen("in.txt","r",stdin);
scanf("%lld%lld",&n,&k);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
sort(a+1,a+n+1);
ll ans1=0,ans2=0,ans3=0;
for(int i=1;i<n;i++){
l=lower_bound(a+i+1,a+n+1,1.0*k/a[i])-a;
r=upper_bound(a+i+1,a+n+1,1.0*k/a[i])-a;
if(l==n+1) ans3+=n-i;
else{
ans1+=n-r+1;
ans2+=r-l;
ans3+=l-i-1;
}
}
printf("%lld %lld %lld\n",ans1,ans2,ans3);
return 0;
}
牛客 小红的375
375=3*125,所给的数必须要被3和125整除,3好判断,而被125整除的数后三位有8种情况分别是:"000","500","250","750","125","375","625","875";如果后三位能凑出这八种情况并且无前导零,就可以满足条件
小红的375(思维+数学)_lgz0921的博客-CSDN博客
#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<cstdio>
#include<iomanip>
#include<map>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
const int mod=1000000007;
string check[8]={"000","500","250","750","125","375","625","875"};
bool flag=false;
int mp[11];
int main(){
//freopen("in.txt","r",stdin);
string s;
int sum=0;
cin>>s;
memset(mp,0,sizeof(mp));
for(int i=0;i<s.size();i++){
sum+=s[i]-'0';
mp[s[i]-'0']++;
}
if(sum%3!=0){
cout<<-1<<endl;
return 0;
}
for(int i=0;i<8;i++){
for(int j=0;j<3;j++)
mp[check[i][j]-'0']--;
int k;
for(k=0;k<=9;k++){
if(mp[k]<0) break;
}
if(k>=10){
for(int j=9;j>=0;j--){
while(mp[j]>0){
cout<<j;
mp[j]--;
}
}
cout<<check[i]<<endl;
flag=1;break;
}
for(int j=0;j<3;j++) mp[check[i][j]-'0']++;
}
if(!flag) cout<<-1<<endl;
return 0;
}