[蓝桥杯 2024 省 Python B] 连连看 题解

暴力思路

首先想到的肯定是这种思路:枚举每组点对,判断其是否满足题目中的两个要求。

时间复杂度:O(n^4)。但看一下数据范围:$n \le 1000$,不用说是过不了的。

AC思路

我们先观察一下条件:第一条是 $|a-c| = |b-d| > 0$,其要求大于零表示该点对的点不能是同一个点。还有要求横坐标之差等于纵坐标之差,我们可以发现:满足该要求的点对必然是某一正方形的其中一对对角。所以我们可以不断构造这样的点对,只要判断一下点对上的两个数是否相等。具体操作方法如下:

1. 选定一个点,作为点对中的一个点。
2. 将选定的点的横坐标与纵坐标加减同样的值得出另外一个点的坐标,于是这两个点的坐标必定满足条件一:$|a-c| = |b-d| > 0$
3. 判断这两个点是否满足条件二:两点上的值相等,如果满足条件,将答案累加。

注意
  • 点对 $(a,b)$$(c,d)$ 与另外一个点对 $(c,d)$$(a,b)$ 是两个不同的点对。

该做法时间复杂度:$O(n^3)$。因为时限是两秒,所以还是可以过的。

于是我们得出了下面的代码(先别急,这份代码过不了):

#include<bits/stdc++.h>

using namespace std;

int n,m,a[1005][1005],ans;

int main()
{
    
    cin>>n>>m;
    
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>a[i][j];
    
  
    //两个点,一个在左上,一个在右下的情况:
    for(int i=1;i<n;i++)
        for(int j=1;j<m;j++)
        {
            int x=i+1,y=j+1;
            //将选定的点的横坐标与纵坐标加上同样的值得出另外一个点的坐标
            for(;x<=n&&y<=m;x++,y++)
            {
                if(a[x][y]==a[i][j])//判定是否相等 
                    ans++;
            }
        }
    
    //两个点,一个在右上,一个在左下的情况:
    for(int i=1;i<n;i++)
        for(int j=m;j>1;j--)
        {
            int x=i+1,y=j-1;
            //将选定的点的横坐标与纵坐标加减同样的值得出另外一个点的坐标
            for(;x<=n&&y>=1;x++,y--)
            {
                if(a[x][y]==a[i][j])//判定是否相等 
                    ans++;
            }
        }
    
    cout<<ans*2;//每种点对倒过来,又是另一种点对,所以乘2
    
    return 0;
}


这份代码如果提交,会TLE两个点,所以得优化一下。  
我们不妨把

if(a[x][y]==a[i][j])
    ans++;


换成三目运算符,写成这样 (a[x][y]==a[i][j]?2:0)。因为每发现一个合法的点对把两个点倒过来又是另一种点对,那干脆每次直接累加两个,答案也不用乘 $2$ 再输出了。用完三目运算符,速度会快一些,就AC了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值