最近准备参加csp认证,做了几套题,放假闲的无聊写一下解析。
一般csp认证的第三道大题都是小模拟,主要考验我们做题者的阅读能力(最重要的!!!)以及敲代码的熟练程度,基本不会涉及到算法,适合我这种不会算法的小弱鸡。
问题信息:
本题不用考虑时间复杂度的问题,只有个别模拟题需要上算法降一下时间
问题背景:(没啥卵用基本不用看)
问题描述:
这是前40%部分分的题干
全部题干
我们先简单读一下题干
1.就是直接读入a矩阵
3.如图所示螺旋地读入初始M矩阵
如果想要按照图示顺序读入矩阵,我们就需要找到它读入的顺序,我们先把前八组数据进行读入
for(int i=1;i<=8;i++){
for(int j=1;j<=i;j++){
if(i%2==0) scanf("%lf",&M[j][i+1-j]);
else scanf("%lf",&M[i+1-j][j]);
}
}
由于读入数据的方向会改变,所以要进行分类讨论(是否能被2整除来判断方向是斜向上还是斜向下)。我们还可以找到一组规律:在前八斜行中,一斜行x+y=i+1。这样就能得出读入时的顺序。
for(int i=7;i>=1;i--){
for(int j=1;j<=i;j++){
if(i%2==0) scanf("%lf",&M[8-i+j][9-j]);
else scanf("%lf",&M[9-j][8-i+j]);
}
}
后7行的规律相近,x+y=17-i。
4.M[i][j]*=a[i][j]
到此就可以得到40分。
5.按题目给出的公式计算M'矩阵的值
注意这里是累加两次总过8*8=64次运算
double change(int x,int y){
double ans=0;
for(int i=1;i<=8;i++){
for(int j=1;j<=8;j++){
int u=i-1,v=j-1;
double au=1,av=1;
if(u==0) au=pow(0.5,0.5);
if(v==0) av=pow(0.5,0.5);
ans+=au*av*M[i][j]*cos(pi/8*u*(x-0.5))*cos(pi/8*v*(y-0.5));
}
}
return ans/4;
}
一开始写代码时没注意矩阵是从0开始存的,我习惯从1开始存,所以u=i-1,v=j-1。
这道题属实没什么难度,到这里就基本结束了。。。。。。
6.最后一步加128然后判断a[i][j]大小不到0就输出0,大于255输出255,在这之间的四舍五入输出。(直接用c++自带的round就可)
最后贴一下代码(小弱鸡代码量小写的比较难看,如果有幸被大佬看到了请轻喷)
#include<bits/stdc++.h>
using namespace std;
int n,T;
double a[10][10];
double M[10][10];
double pi=acos(-1);
void get(int n){
int num=0;
for(int i=1;i<=8;i++){
for(int j=1;j<=i;j++){
if(i%2==0) scanf("%lf",&M[j][i+1-j]);
else scanf("%lf",&M[i+1-j][j]);
num++;
if(num==n) return;
}
}
for(int i=7;i>=1;i--){
for(int j=1;j<=i;j++){
if(i%2==0) scanf("%lf",&M[8-i+j][9-j]);
else scanf("%lf",&M[9-j][8-i+j]);
num++;
if(num==n) return;
}
}
}
void print(){
for(int i=1;i<=8;i++){
for(int j=1;j<=8;j++) printf("%d ",int(M[i][j]));
printf("\n");
}
}
double change(int x,int y){
double ans=0;
for(int i=1;i<=8;i++){
for(int j=1;j<=8;j++){
int u=i-1,v=j-1;
double au=1,av=1;
if(u==0) au=pow(0.5,0.5);
if(v==0) av=pow(0.5,0.5);
ans+=au*av*M[i][j]*cos(pi/8*u*(x-0.5))*cos(pi/8*v*(y-0.5));
}
}
return ans/4;
}
int main(){
for(int i=1;i<=8;i++){
for(int j=1;j<=8;j++){
scanf("%lf",&a[i][j]);
}
}
scanf("%d%d",&n,&T);
get(n);
if(T==0){
print();
return 0;
}
for(int i=1;i<=8;i++)
for(int j=1;j<=8;j++) M[i][j]*=a[i][j];
if(T==1){
print();
return 0;
}
for(int i=1;i<=8;i++)
for(int j=1;j<=8;j++) a[i][j]=change(i,j)+128;//复用一下a
for(int i=1;i<=8;i++){
for(int j=1;j<=8;j++){
if(a[i][j]<0) printf("0 ");
else if(a[i][j]>255) printf("255 ");
else printf("%d ",int(round(a[i][j])));
}
printf("\n");
}
return 0;
}
完!