CCF CSP 2023 5-1.2

重复局面

问题描述

国际象棋每一个局面可以用大小为 8×8 的字符数组来表示,其中每一位对应棋盘上的一个格子。六种棋子王、后、车、象、马、兵分别用字母 kqrbnp 表示,其中大写字母对应白方、小写字母对应黑方。棋盘上无棋子处用字符 * 表示。两个字符数组的每一位均相同则说明对应同一局面。

现已按上述方式整理好了每步棋后的局面,试统计每个局面分别是第几次出现。

输入格式

从标准输入读入数据。

输入的第一行包含一个正整数 n,表示这盘棋总共有 n 步。

接下来 8×n 行,依次输入第 1 到第 n 步棋后的局面。具体来说每行包含一个长度为 8 的字符串,每 8 行字符串共 64 个字符对应一个局面。

输出格式

输出到标准输出中。

输出共 n 行,每行一个整数,表示该局面是第几次出现。

样例输入

8
********
******pk
*****r*p
p*pQ****
********
**b*B*PP
****qP**
**R***K*
********
******pk
*****r*p
p*pQ****
*b******
****B*PP
****qP**
**R***K*
********
******pk
*****r*p
p*p*****
*b**Q***
****B*PP
****qP**
**R***K*
******k*
******p*
*****r*p
p*p*****
*b**Q***
****B*PP
****qP**
**R***K*
******k*
******p*
*****r*p
p*pQ****
*b******
****B*PP
****qP**
**R***K*
********
******pk
*****r*p
p*pQ****
*b******
****B*PP
****qP**
**R***K*
********
******pk
*****r*p
p*p*****
*b**Q***
****B*PP
****qP**
**R***K*
********
******pk
******rp
p*p*****
*b**Q***
****B*PP
****qP**
**R***K*

Data

样例输出

1
1
1
1
1
2
2
1

Data

样例说明

第 6、7 步后的局面分别与第 2、3 步后的局面相同。第 8 步后的局面与上图相对应。

子任务

输入数据满足 n≤100。

提示

判断重复局面仅涉及字符串比较,无需考虑国际象棋实际行棋规则。

语法题一把AC

#include<bits/stdc++.h>

using namespace std;



int main()

{

char s[100][8][8];

    int n;

    cin>> n;

    for(int i=0;i<n;i++){

        for(int j=0;j<8;j++)

            for(int k=0;k<8;k++)

                cin>>s[i][j][k];

    }

    for(int i=0;i<n;i++){

        int ii=0;

        int cnt = 1;

        

        while(ii<i){

            int d=1;

            for(int j=0;j<8;j++){

        

                for(int k=0;k<8;k++){

                    if(s[ii][j][k]!=s[i][j][k])

                    d=0;

                }

                if(d==0) break;

            }

            if(d==1) cnt++;

            

            ii++;

        }

        cout << cnt << endl;

    }

    

}




矩阵运算

问题描述:

题目背景

Softmax(Q×KTd)×V 是 Transformer 中注意力模块的核心算式,其中 Q、K 和 V 均是 n 行 d 列的矩阵,KT 表示矩阵 K 的转置,× 表示矩阵乘法。

问题描述

为了方便计算,顿顿同学将 Softmax 简化为了点乘一个大小为 n 的一维向量 W:
(W⋅(Q×KT))×V
点乘即对应位相乘,记 W(i) 为向量 W 的第 i 个元素,即将 (Q×KT) 第 i 行中的每个元素都与 W(i) 相乘。

现给出矩阵 Q、K 和 V 和向量 W,试计算顿顿按简化的算式计算的结果。

输入格式

从标准输入读入数据。

输入的第一行包含空格分隔的两个正整数 n 和 d,表示矩阵的大小。

接下来依次输入矩阵 Q、K 和 V。每个矩阵输入 n 行,每行包含空格分隔的 d 个整数,其中第 i 行的第 j 个数对应矩阵的第 i 行、第 j 列。

最后一行输入 n 个整数,表示向量 W。

输出格式

输出到标准输出中。

输出共 n 行,每行包含空格分隔的 d 个整数,表示计算的结果。

样例输入

3 2
1 2
3 4
5 6
10 10
-20 -20
30 30
6 5
4 3
2 1
4 0 -5

Data

样例输出

480 240
0 0
-2200 -1100

Data

子任务

70 的测试数据满足:n≤100 且 d≤10;输入矩阵、向量中的元素均为整数,且绝对值均不超过 30。

全部的测试数据满足:n≤104 且 d≤20;输入矩阵、向量中的元素均为整数,且绝对值均不超过 1000。

提示

请谨慎评估矩阵乘法运算后的数值范围,并使用适当数据类型存储矩阵中的整数。

一把 70 奇怪 (语法流程题)

#include<bits/stdc++.h>

using namespace std;

int hang,lie;

int q[10100][100]={0},k[10100][100]={0},w[10100]={0},v[10100][100]={0};

int cnt[10100][100]={0},kt[10100][100]={0};

int sum[10100][100]={0};



int main()

{

    

cin>> hang>>lie;

    for(int i=0;i<hang;i++){

        for(int j=0;j<lie;j++){

            cin>>q[i][j];

        }

    }

    for(int i=0;i<hang;i++){

        for(int j=0;j<lie;j++){

            cin>>k[i][j];

        }

    }

    int hh=0,ll=0;

    for(int i=0;i<lie;i++){

        hh=0;

        for(int j=0;j<hang;j++){

            kt[i][j]=k[hh][ll];

            hh++;

        }

        ll++;

    }

    for(int i=0;i<hang;i++){

        for(int j=0;j<lie;j++){

            cin>>v[i][j];

        }

    }

    for(int i=0;i<hang;i++){

    cin >> w[i] ;

    }

    

    //q*kt

    

    for(int i=0;i<hang;i++){

        for(int j=0;j<hang;j++){

            for(int r=0;r<lie;r++)

                cnt[i][j]+=q[i][r]*kt[r][j];

        }

    }

    // *wi

    for(int i=0;i<hang;i++){

        for(int j=0;j<hang;j++){

            cnt[i][j]*=w[i];

        }

    }

    for(int i=0;i<hang;i++){

        for(int j=0;j<lie;j++){

            for(int r=0;r<hang;r++)

                sum[i][j]+=cnt[i][r]*v[r][j];

        }

    }

    

    

    for(int i=0;i<hang;i++){

        for(int j=0;j<lie;j++){

        

                cout << sum[i][j]<< " ";

            

        }

        cout << endl;

    }

    

    

}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值