当前位置:文档之家› noip2014普及组复赛题解

noip2014普及组复赛题解

1.珠心算测验注意看清题意:其中有多少个数,恰好等于集合中另外两个(不同的)数之和。

这样的题意加上100的规模,建议暴力3个for:#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;int n;int a[105];int main(){freopen("count.in","r",stdin);freopen("count.out","w",stdout);scanf("%d",&n);for(int i=1; i<=n; i++){scanf("%d",&a[i]);}sort(a+1,a+n+1);int res=0;for(int i=1; i<=n; i++){int ok=0;for(int j=1; j<=n && !ok; j++) if(j!=i){for(int k=1; k<=n && !ok; k++) if(a[k]!=a[j]){if(a[j]+a[k]==a[i]) ok=1;}}res+=ok;}printf("%d\n",res);return 0;}2.比例简化L很小,还是枚举,然后比较的话建议用乘法比较,避免精度问题:#include<cstdio>#include<cstring>#include<iostream>using namespace std;int A,B,L;int gcd(int a,int b){if(b==0) return a;return gcd(b,a%b);}int main(){freopen("ratio.in","r",stdin);freopen("ratio.out","w",stdout);scanf("%d%d%d",&A,&B,&L);int ba=1000000,bb=1;for(int i=1; i<=L; i++){for(int j=1; j<=L; j++){if(gcd(i,j)==1 && i*B>=j*A){if(ba*j>=bb*i){ba=i, bb=j;}}}}printf("%d %d\n",ba,bb);return 0;}3.螺旋矩阵没一圈的数量有规律的,最外面一圈(n-1)*4,然后每往里n-2,直到后要么只有一个点,要么4个点。

所以可以先确定是在哪圈里,然后暴力走一圈就行:#include<cstdio>#include<cstring>#include<iostream>using namespace std;int n,x,y;int solve(){scanf("%d%d%d",&n,&x,&y);int ceng=min(x, n+1-x);ceng=min(ceng, min(y, n+1-y));int num=0, len=n-1;for(int i=1; i<ceng; i++,len-=2){int ad;if(len==0) ad=1;else ad=len*4;num+=ad;}num++;int nx=ceng, ny=ceng;if(nx==x && ny==y) return num;for(int i=1; i<=len; i++) {ny++; num++;if(nx==x && ny==y) return num;}for(int i=1; i<=len; i++){nx++; num++;if(nx==x && ny==y) return num;}for(int i=1; i<=len; i++){ny--; num++;if(nx==x && ny==y) return num;}for(int i=1; i<len; i++){nx--; num++;if(nx==x && ny==y) return num;}return -1;}int main(){freopen("matrix.in","r",stdin);freopen("matrix.out","w",stdout);int res=solve();printf("%d\n",res);return 0;}4.子矩阵可以用二进制状态枚举取了哪些列,然后对于行的选取,可以DP,预处理每一行的代价,任意两行之间的代价,那么dp[j][i]=min(dp[j][i], dp[k][i-1]+val[k][j]+dp[j][1]);代码写的不是很顺,为了调试写了很多输出注释语句:#include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>using namespace std;int g[25][25],f[25][25],dp[25][25],val[25][25];int n,m,x,y,res;int count(int v){int ret=0;while(v){if(v&1) ret++;v>>=1;}return ret;}void gao(){//printf("gao\n");for(int i=1; i<=n; i++){for(int j=i+1; j<=n; j++){val[i][j]=0;for(int k=1; k<=y; k++) val[i][j]+=abs(f[i][k]-f[j][k]);//printf("%d %d = %d\n",i,j,val[i][j]);}}for(int i=1; i<=x; i++){for(int j=i; j<=n; j++) dp[j][i]=100000000;}for(int i=1; i<=n; i++){dp[i][1]=0;for(int j=2; j<=y; j++){dp[i][1]+=abs(f[i][j]-f[i][j-1]);}}//printf("ok\n");for(int i=2; i<=x; i++){for(int j=i; j<=n; j++){//dp[j][i]=100000000;for(int k=i-1; k<j; k++){dp[j][i]=min(dp[j][i],dp[k][i-1]+val[k][j]+dp[j][1]);//printf("%d %d = %d %d\n",j,i,dp[j][i],dp[k][i-1]);}}}for(int i=x; i<=n; i++) res=min(res, dp[i][x]);// printf("res=%d\n",res);}void solve(){scanf("%d%d%d%d",&n,&m,&x,&y);for(int i=1; i<=n; i++){for(int j=1; j<=m; j++) {scanf("%d",&g[i][j]);}}res=100000000;for(int i=0; i<(1<<m); i++){if(count(i)!=y) continue;//printf("mask = %d\n",i);int r=0;for(int j=0; j<m; j++){if( ((i>>j)&1) ==0) continue;++r;for(int k=1; k<=n; k++) f[k][r]=g[k][j+1];}/*for(int j=1; j<=n; j++){for(int k=1; k<=y; k++) printf("%d ",f[j][k]);printf("\n");}printf("\n");*/gao();}printf("%d\n",res);}int main(){freopen("submatrix.in","r",stdin);freopen("submatrix.out","w",stdout);solve();return 0;}。

相关主题