CSP202212_3
CSP202212_3
题目
思路
比较直观的大模拟,仔细地读一遍题后就基本可以明确要求了。
首先针对一个长度为 n 的序列,按 Z 形填入矩阵中。直观地想,总共需要斜着填15行,奇数行都是从左下向右上,偶数行都是从右上向左下,手模一下基本就可以得出结果了。20pts到手
对填入的矩阵,直接和所给矩阵相乘即可完成第二个要求,没有任何难度。40pts到手。
进行离散变换本质上就是一个数学计算过程。相关的数学知识题目都已给出,注意在计算时如果矩阵从 [1, 1] 开始存储,坐标到 u、v 需要平移一次。此外如果用分数计算,注意不要损失精度。最后用 round 函数四舍五入一下,加上 128 并判断一下范围即可AC。
挺水的题目,基本不涉及什么有难度的处理。码量也不大,下面的代码很多地方可以省去,但是懒得改了。总而言之只要细心拿满分还是比较容易的。
Code
#include<bits/stdc++.h>
const double pi = acos(-1);
using namespace std;
int n, opt;
double q[9][9];
double m[9][9];
double ans[9][9];
double num[1010];
double alpha(int x)
{
if(x) return 1;
return sqrt(0.5);
}
double cal(int a, int b)
{
double sum = 0;
for(int i = 1;i <= 8;i++)
{
for(int j = 1;j <= 8;j++)
{
int u = i - 1, v = j - 1;
//u、v要平移到[0, 7],a、b也要对应减一
sum += m[i][j] * (alpha(u)*alpha(v)) * (cos((a - 0.5)*u*(pi/8.0))*cos((b - 0.5)*v*(pi/8.0)));
}
}
sum /= 4.0;
return sum;
}
void zmove()
{
int pos = 0;
for(int i = 1;i <= 15;i++)
{
int dir = i%2;
int sx = 0, sy = 0;
// dir = 0 => ↙
// dir = 1 => ↗
if(i <= 8)
{
if(! dir)
sx = 1, sy = i;
else
sx = i, sy = 1;
for(int k = 1;k <= i;k++)
{
m[sx][sy] = num[++pos];
if(! dir)
sx++, sy--;
else
sx--, sy++;
}
}
else
{
if(! dir)
sx = i - 7, sy = 8;
else
sx = 8, sy = i - 7;
for(int k = 1;k <= 16 - i;k++)
{
m[sx][sy] = num[++pos];
if(! dir)
sx++, sy--;
else
sx--, sy++;
}
}
if(pos == n) break;
}
return;
}
void func(int opt)
{
zmove();
if(opt == 0)
{
for(int i = 1;i <= 8;i++)
{
for(int j = 1;j <= 8;j++)
{
cout << m[i][j] << " ";
}
cout << endl;
}
return;
}
for(int i = 1;i <= 8;i++)
{
for(int j = 1;j <= 8;j++)
{
m[i][j] *= q[i][j];
}
}
if(opt == 1)
{
for(int i = 1;i <= 8;i++)
{
for(int j = 1;j <= 8;j++)
{
cout << m[i][j] << " ";
}
cout << endl;
}
return;
}
for(int i = 1;i <= 8;i++)
{
for(int j = 1;j <= 8;j++)
{
ans[i][j] = round(cal(i, j));
ans[i][j] += 128;
if(ans[i][j] < 0) ans[i][j] = 0;
if(ans[i][j] > 255) ans[i][j] = 255;
}
}
for(int i = 1;i <= 8;i++)
{
for(int j = 1;j <= 8;j++)
{
cout << ans[i][j] << " ";
}
cout << endl;
}
return;
}
int main()
{
for(int i = 1;i <= 8;i++)
{
for(int j = 1;j <= 8;j++)
{
cin >> q[i][j];
}
}
cin >> n >> opt;
for(int i = 1;i <= n;i++)
{
cin >> num[i];
}
func(opt);
return 0;
}
/*
16 11 10 16 24 40 51 61
12 12 14 19 26 58 60 55
14 13 16 24 40 57 69 56
14 17 22 29 51 87 80 62
18 22 37 56 68 109 103 77
24 35 55 64 81 104 113 92
49 64 78 87 103 121 120 101
72 92 95 98 112 100 103 99
26
2
-26 -3 0 -3 -2 -6 2 -4 1 -3 1 1 5 1 2 -1 1 -1 2 0 0 0 0 0 -1 -1
*/

浙公网安备 33010602011771号