CSP202305-1 重复局面(100分)【顺序查找+map】

试题编号: 202305-1
试题名称: 重复局面
时间限制: 1.0s
内存限制: 512.0MB
问题描述:

题目背景
国际象棋在对局时,同一局面连续或间断出现3次或3次以上,可由任意一方提出和棋。

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

现已按上述方式整理好了每步棋后的局面,试统计每个局面分别是第几次出现。
在这里插入图片描述

输入格式
从标准输入读入数据。
输入的第一行包含一个正整数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*

样例输出

1
1
1
1
1
2
2
1

子任务
输入数据满足n≤100。

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

问题链接CSP202305-1重复局面
问题简述:(略)
问题分析
解法一:顺序查找
用C语言来编程,运行时间比用C++和STL相对运行时间短。
顺序查找是一种经典的解题方法。每次读入局面时,把局面及其出现次数放在结构数组的最后一个元素中,然后再结构数组中顺序查找并计数,最后输出结果。
解法二:使用map
  用C++语言来编程。
  用STL的map来统计重复次数比较方便。
程序说明:(略)
参考链接:(略)
题记:(略)

100分的C语言程序(解法一)如下:

/* CSP202305-1 重复局面 */

#include <stdio.h>
#include <string.h>

#define N 8
#define M 100

char s[N + 1];
struct {
    char s[N * N + 1];
    int cnt;
} a[M + 1];

int main()
{
    int n, i, j, k = 0;

    scanf("%d", &n);

    for (i = 1; i <= n; i++) {
        a[k].s[0] = '\0';
        a[k].cnt = 1;

        for (j = 1; j <= N; j++) {
            scanf("%s", s);
            strcat(a[k].s, s);
        }

        for (j = 0; j <= k; j++)
            if (strcmp(a[j].s, a[k].s) == 0) {
                if (j != k) a[j].cnt++;
                break;
            }
        if (j == k) k++;

        printf("%d\n", a[j].cnt);
    }

    return 0;
}

100分的C++语言程序(解法二)如下:

/* CSP202305-1 重复局面 */

#include <iostream>
#include <map>

using namespace std;

map<string, int> mp;

int main()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        string s, a;
        for (int j = 1; j <= 8; j++) {
            cin >> a;
            s += a;
        }

        cout << ++mp[s] << endl;
    }

    return 0;
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值