@
答案是1478
答案14(如果012算的话)
数据范围1e18,所以不能直接暴力,先取余,再暴力剩下的
#include<bits/stdc++.h>using namespace std;#define rep(i,m,n) for(int i=m;i<=n;i++)#define per(i,m,n) for(int i=m;i>=n;i--)#define pair<int,int> PII#define int long longsigned main(){ int a,b,n; cin>>a>>b>>n; int ans=0,cnt=0; int x=5*a+2*b;//一周刷题数 ans=n/x*7; n=n%x; while(1) { if(cnt>=n) break; ans++; if(ans%7==0||ans%7==6) cnt+=b; else cnt+=a; } cout<<ans; return 0;}先读题
然后结论就是直接取左右两边最大的二倍
#include<bits/stdc++.h>using namespace std;#define pair<int,int> PII#define int long longconst int N=1e4+10;int a[N];signed main(){ int n; cin>>n; for(int i=1;i<=n;i++) { int l,r; l=(i-1)*2; r=(n-i)*2; cout<<max(l,r)<<endl; } return 0;}这个题读了半天才懂,注意他说的进制是指逢几进一,
答案就是每一位取能取的最小进制
这里面的321=((3*10+2)*2)+1=65
也可以这样算 1+2*2+3*10*2=65
#include<bits/stdc++.h>using namespace std;#define pair<int,int> PII#define int long longconst int mod=1e9+7;const int N=1e4+10;int a[N],b[N],c[N],p[N];signed main(){ int k,ma,mb; cin>>k>>ma; for(int i=ma;i>=1;i--) cin>>a[i]; cin>>mb; for(int i=mb;i>=1;i--) cin>>b[i]; int n=max(ma,mb); for(int i=1;i<=n;i++) c[i]=a[i]-b[i]; for(int i=n;i>=1;i--) { int pp=2; pp=max(pp,max(a[i],b[i])+1);//最低p进制 p[i+1]=pp; } int ans=0; for(int i=n;i>=2;i--) { c[i-1]+=c[i]*p[i]; } cout<<c[1]<<endl; return 0;}直接暴力的话(n^6) 铁炸!
使用前缀和+暴力的话(n^4) 也会炸
最后一维用二分优化(n^3*log n) 可能会炸,但我想不到更好的了
#include<bits/stdc++.h>using namespace std;#define pair<int,int> PII#define int long longconst int N=5e2+10;int a[N][N],sum[N][N];int n,m,K;int S(int x2,int y2,int x1,int y1){ return sum[x1][y1]-sum[x1][y2-1]-sum[x2-1][y1]+sum[x2-1][y2-1];}signed main(){ cin>>n>>m>>K; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>a[i][j]; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j]; int ans=0; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(a[i][j]>K)continue; for(int k=i;k<=n;k++) { int l=j,r=m; while(l<r) { int mid=l+r+1>>1; if(S(i,j,k,mid)<=K)l=mid; else r=mid-1; } if(S(i,j,k,l)>K)continue; //printf("%lld %lld %lld %lld\n",i,j,k,l); ans+=(l-j+1); } } } cout<<ans<<endl; return 0;}状态压缩DP
f[i][j]表示已经摆完前i列,且突出来的状态为j
假如j=1:就是凸出来了上面那一块
#include<bits/stdc++.h>using namespace std;#define pair<int,int> PII#define int long longconst int mod=1e9+7;const int M=1<<2;const int N=1e7+10;int f[N][M];signed main(){ int n; cin>>n; f[0][0]=1; for(int i=1;i<=n+1;i++) { f[i][0]=(f[i][0]+f[i-1][0]+f[i-1][3])%mod;//不突出 f[i][1]=(f[i][1]+f[i-1][2]+f[i-1][0])%mod;//上面突出 f[i][2]=(f[i][2]+f[i-1][1]+f[i-1][0])%mod;//下面突出 f[i][3]=(f[i][3]+f[i-1][0]+f[i-1][1]+f[i-1][2])%mod;//突出两个 } cout<<f[n][0]<<endl; return 0;}第一维可以用滚动数组优化
#include<bits/stdc++.h>using namespace std;#define pair<int,int> PII#define int long longconst int mod=1e9+7;const int M=1<<2;int f[3][M];signed main(){ int n; cin>>n; f[0][0]=1; for(int i=1;i<=n+1;i++) { f[i&1][0]=(f[i-1&1][0]+f[i-1&1][3])%mod;//不突出 f[i&1][1]=(f[i-1&1][2]+f[i-1&1][0])%mod;//上面突出 f[i&1][2]=(f[i-1&1][1]+f[i-1&1][0])%mod;//下面突出 f[i&1][3]=(f[i-1&1][0]+f[i-1&1][1]+f[i-1&1][2])%mod;//突出两个 } cout<<f[n&1][0]<<endl; return 0;}直接两重循环建边+dfs搜索的,会炸(因为建边是两重循环,过不叫第二个5e4的样例)
注意不能并查集,因为a引爆b,但b不一定能引爆a
正解应该是看那个r(r<=10),不会....
#include<bits/stdc++.h>using namespace std;#define pair<int,int> PII#define int long longconst int N=1e3+10;vector<int> q[N];int x[N],y[N],r[N];int n,m;bool vis[N];bool v[N];int cnt;bool check(int x1,int y1,int r1,int x2,int y2){ return (x2-x1)*(x2-x1)+(y2-x1)*(y2-y1)<=r1*r1;//1会引炸2}void dfs(int x){ cnt++; for(int i=0;i<q[x].size();i++) { int j=q[x][i]; if(vis[j]||v[N])continue; v[j]=1; dfs(j); }}signed main(){ cin>>n>>m; for(int i=1;i<=n;i++) { cin>>x[i]>>y[i]>>r[i]; } for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(i==j)continue; if(check(x[i],y[i],r[i],x[j],y[j])) { q[i].push_back(j); } } } while(m--) { int xx,yy,rr; cin>>xx>>yy>>rr; for(int i=1;i<=n;i++) { if(check(xx,yy,rr,x[i],y[i])) { vis[i]=1; } } } for(int i=1;i<=n;i++) { if(vis[i]) dfs(i); } cout<<cnt<<endl; return 0;}dp,考虑遇到店或者花
f[i][j][k]表示已经走了i次,有j次经过了酒馆,还剩k斗酒
记录酒的时候只需要斗里有100以下的容量 ,因为最多走100次也就是最多喝100斗酒,太多了喝不完
#include<bits/stdc++.h>using namespace std;#define pair<int,int> PII#define int long longconst int mod=1e9+7;const int N=100+10;int n,m;int f[N+N][N+N][N];//f[i][j][k]表示已经走了i次,有j次经过了酒馆,还剩k斗酒signed main(){ cin>>n>>m; f[0][0][2]=1; for(int i=1;i<=n+m;i++) { for(int j=0;j<=i;j++) { for(int k=0;k<100;k++) { f[i][j][k]=(f[i][j][k]+f[i-1][j][k+1])%mod; if(j>=1&&k%2==0) f[i][j][k]=(f[i][j][k]+f[i-1][j-1][k/2])%mod; } } } cout<<f[n+m-1][n][1]<<endl; return 0;}这个没时间写了,随便写的