你没看错,一个前NOI Ag选手来做普及组了,马上打ICPC了我也准备练习一些。
连PJ都不会了,得分:100+100+30+100=330,甚至比初三还菜,nowcoder数据,思路也应该是这个分。
写一发题解吧(T3就写30分的)
T1
奇数直接输出-1,偶数按二进制位拆分
#include<bits/stdc++.h> using namespace std; int n; int main() { cin>>n; if(n%2==1)cout<<-1; else for(int i=(1<<30);i>=2;i>>=1) if(i<=n)n=n-i,cout<<i<<' '; }
T2
用个筒存一下每个分数上有多少人,每次加人的时候从大到小搜索一遍即可
#include<bits/stdc++.h> using namespace std; int n,w,a[601]; int main() { scanf("%d%d",&n,&w); for(int i=1,x;i<=n;i++) { scanf("%d",&x),a[x]++; int t=max(1,i*w/100); for(int j=600;j>=0;j--) if(a[j]>=t){printf("%d ",j);break;}else t-=a[j]; } }
T3
不会做,只会暴力,就是开一个栈,每次遇到 | 或 & 弹出栈顶两个元素运算,遇到 ! 弹出栈顶一个元素运算,裸暴力复杂度O(n^2)。看上去像是一个动态DP,但我早就不会写那个玩意了。
#include<bits/stdc++.h> using namespace std; int n,m,tp,sz,a[100007],st[100007]; string s; int main() { getline(cin,s); scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); scanf("%d",&m); sz=s.size(); while(m--) { int i=0,x,t,t1,t2; scanf("%d",&x),a[x]^=1; tp=0; while(i<sz) { while(i<sz&&s[i]==' ')i++; if(s[i]=='x') { t=0,i++; while(i<sz&&s[i]>='0'&&s[i]<='9')t=t*10+s[i++]-'0'; st[++tp]=a[t]; } if(s[i]=='!')st[tp]^=1,i++; if(s[i]=='&')t1=st[tp--],t2=st[tp--],st[++tp]=(t1&t2),i++; if(s[i]=='|')t1=st[tp--],t2=st[tp--],st[++tp]=(t1|t2),i++; while(s[i]==' ')i++; } printf("%d ",st[tp]),a[x]^=1; } }
T4
70分做法很容易想到f[i][j]表示走到第j列,在第i行准备转弯的最大值,于是枚举上一行准备转弯的地方,对矩阵每一列做前缀和即可。
100分做法实际上是70分的优化,其实不需要枚举最后一次,直接f[i][j][0/1]表示在i,j往上/下走,从上一个方向推过来就行了,注意细节。
#include<bits/stdc++.h> using namespace std; typedef long long ll; int n,m; ll a[1005][1005],f[1005][1005][2]; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)scanf("%lld",&a[i][j]); for(int i=1;i<=n;i++)f[i][0][0]=f[i][0][1]=-1e18; for(int j=1;j<=m;++j) { if(j==1)f[1][1][0]=a[1][1];else f[1][j][0]=max(f[1][j-1][0],f[1][j-1][1])+a[1][j]; for(int i=2;i<=n;i++) f[i][j][0]=max(f[i-1][j][0],max(f[i][j-1][0],f[i][j-1][1]))+a[i][j]; if(j==1) { f[1][1][1]=a[1][1]; for(int i=2;i<=n;i++)f[i][j][1]=-1e18; continue; } f[n][j][1]=max(f[n][j-1][0],f[n][j-1][1])+a[n][j]; for(int i=n-1;i;i--) f[i][j][1]=max(f[i+1][j][1],max(f[i][j-1][0],f[i][j-1][1]))+a[i][j]; } printf("%lld",max(f[n][m][0],f[n][m][1])); }