第二十三天 2021-4-6 备战CSP
刷题模块:CSP 202006-4
一、矩阵快速幂
教程文章通俗易懂,一应俱全:矩阵快速幂——入门
整数快速幂模板
int quickPow(int a,int n){ //快速幂
int ans = 1;
while(n){
if(n&1) ans*=a;
a *= a;
n /= 2;
}
return ans;
}
矩阵快速幂模板
void Matrix(int (&a)[2][2],int b[2][2]){ //矩阵乘法
int tmp[2][2] = {0};
for(int i = 0; i < 2; ++i)
for(int j = 0; j < 2; ++j)
for(int k = 0; k < 2; ++k)
tmp[i][j] = (tmp[i][j] + a[i][k] * b[k][j]) % N; //矩阵相乘,注意mod
for(int i = 0; i < 2; ++i)
for(int j = 0; j < 2; ++j)
a[i][j] = tmp[i][j]; //赋值返回数据
}
//cot 结果数组,初始为单位矩阵
//temp底数数组,为幂的底数
void quickPow(){ //快速幂
while(n){
if(n & 1) Matrix(cot,temp); //如果是奇数
Matrix(temp,temp);
n /= 2; //不断除2
}
}
二、202006-4
202006-4 CCF CSP认证 1246(digits) 96分 动态规划
★:动态规划DP递推公式如何转为递推矩阵
有如下动态规划递推公式:
state[i][1]=state[i-1][2];
state[i][2]=state[i-1][3]+state[i-1][4];
state[i][3]=state[i-1][1];
state[i][4]=state[i-1][1]+state[i-1][2];
则可以得出递推矩阵:
已知初始状态S、递推关系矩阵A以及他们的递推关系:
则可以得出任意状态的值,其中关系矩阵A的i次方由矩阵快速幂计算:
三、201604-1
Debug点:
注意unsigned int的使用,若进行了两个整数的减法,并可能结果为负数,则不能使用unsigned int。
#include<iostream>
#include<cstdio>
using namespace std;
int n;
int sumDay, d1, d2;
bool flag;
int main(){
sumDay = 0;
flag = true;
scanf("%d", &n);
if(n == 1){
scanf("%d", &d1);
n--;
}
else {
scanf("%d %d", &d1, &d2);
flag = (d2 - d1) > 0;
n = n - 2;
}
while(n--) {
d1 = d2;
scanf("%d", &d2);
if((d2 - d1) > 0){
if(!flag) sumDay++;
flag = true;
}
else{
if(flag) sumDay++;
flag = false;
}
}
printf("%d\n", sumDay);
return 0;
}
四、201604-2
写了很长时间,逻辑思维还有点混乱,但是没想到竟然一遍过了
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
bool arr[20][15];
bool block[4][4];
int arrTop[10],blockBottom[4];
int pos;
void init(){
for(int i=0;i<10;i++){
arrTop[i]=15;
}
for(int i=0;i<4;i++){
blockBottom[i]=-15;
}
}
int main() {
freopen("in.txt","r",stdin);
init();
for(int i = 0; i < 15; i++) {
for(int j = 0; j < 10; j++) {
scanf("%d", &arr[i][j]);
if(arr[i][j] && i < arrTop[j]){
arrTop[j] = i;
}
}
}
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++){
scanf("%d", &block[i][j]);
if(block[i][j] && i > blockBottom[j]){
blockBottom[j] = i;
}
}
}
scanf("%d", &pos);
int contactDis = 15, contactCol=0;
for(int b = 0, a = pos-1; b < 4; b++, a++){
if(arrTop[a] - blockBottom[b] < contactDis){
contactDis = arrTop[a] - blockBottom[b];
contactCol = b;
}
}
int bottomCol=0;
for(int i=0;i<4;i++){
bottomCol=max(bottomCol,blockBottom[i]);
}
int contactPos = arrTop[contactCol+pos-1]-blockBottom[contactCol]-1;
for(int bi = 0, ai = contactPos; bi <= bottomCol; bi++, ai++) {
for(int bj = 0, aj = pos - 1; bj < 4; bj++, aj++) {
if(!arr[ai][aj] && block[bi][bj]){
arr[ai][aj] = block[bi][bj];
}
}
}
for(int i = 0; i < 15; i++) {
for(int j = 0; j < 10; j++) {
printf("%d", arr[i][j]);
if(j != 9) printf(" ");
}
printf("\n");
}
return 0;
}