poj1021 概率,最小表示

博客探讨了一种概率算法,用于确定连成一片的棋子形状是否相同。通过为每颗棋子计算一个值(基于与其水平和垂直方向相连的棋子数+1),然后比较排序后的序列来推测棋盘形状的等价性。举例说明,如棋子C的值为4(水平AB+垂直G+自身)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个真的很强!网上找的:

唯一的难点是,怎么判断连成一片的棋子形状相同? 一个基于概率的算法是:给每一颗棋子计算一个值,根据这个值是否相等来推测它所在的一片棋子的形状是否相等。计算出每颗棋子的值后对其进行排序,若两副棋盘生成的序列完全相等则推测其等价。

    至于这个值如何定,我的设计为:每颗棋子在其水平方向和垂直方向与其相连的棋子总数+1(自己)。比如左图的C,这个值为水平相连2颗(AB)+垂直相连1颗(G)+1=4。

#include <iostream>
using namespace std;
int a[101][101],b[10010],c[10010],d,e,ans,x[10010],y[10010],n,m,k,cas;
int main() {
    scanf("%d",&cas);
    while (cas--) {
          scanf("%d%d%d",&n,&m,&k);
          memset(a,0,sizeof(a));
          for (int i=1;i<=k;i++) {
              scanf("%d%d",&x[i],&y[i]);
              a[x[i]][y[i]] = 1;
          }
          memset(b,0,sizeof(b));
          for (int i=1;i<=k;i++) {
              b[i] = 1;
              d = x[i]; e = y[i];
              while (d<n-1 && a[d+1][e]==1) {
                    b[i]++;
                    d++;
              }
              d = x[i]; e = y[i];
              while (d>0 && a[d-1][e]==1) {
                    b[i]++;
                    d--;
              }
              d = x[i]; e = y[i];
              while (e<m-1 && a[d][e+1]==1) {
                    b[i]++;
                    e++;
              }
              d = x[i]; e = y[i];
              while (e>0 && a[d][e-1]==1) {
                    b[i]++;
                    e--;
              } 
          }
          memset(a,0,sizeof(a));
          for (int i=1;i<=k;i++) {
              scanf("%d%d",&x[i],&y[i]);
              a[x[i]][y[i]] = 1;
          }
          memset(c,0,sizeof(c));
          for (int i=1;i<=k;i++) {
              c[i] = 1;
              d = x[i]; e = y[i];
              while (d<n-1 && a[d+1][e]==1) {
                    c[i]++;
                    d++;
              }
              d = x[i]; e = y[i];
              while (d>0 && a[d-1][e]==1) {
                    c[i]++;
                    d--;
              }
              d = x[i]; e = y[i];
              while (e<m-1 && a[d][e+1]==1) {
                    c[i]++;
                    e++;
              }
              d = x[i]; e = y[i];
              while (e>0 && a[d][e-1]==1) {
                    c[i]++;
                    e--;
              } 
          }
          sort(b+1,b+k+1);
          sort(c+1,c+k+1);
          ans = 1;
          for (int i=1;i<=k;i++)
              if (b[i]!=c[i]) {
                              ans = 0;
                              break;
              }
          if (ans) printf("YES\n");
          else printf("NO\n");
    }
    return 0;
}
              

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值