P16849 [GKS 2021 #D] Arithmetic Square 题解

题目大意

给你一个没有中间格的九宫格,其余格内都有一个整数。问在中间格填入一个整数使某一行、某一列或某一条对角线上的 \(3\) 个数是等差数列的数量最大是多少,同一行、列或对角线上的序列只算作一个序列。

算法分析

直接枚举中间数的所有可能是不行的,我们可以把等差数列分一下类,第一种是不受中间数的影响,第二种受中间数的影响。

首先考虑第一种,显然有四种情况,分别是 \(\{G_{1,1},G_{1,2},G_{1,3}\}\)、\(\{G_{3,1},G_{3,2},G_{3,3}\}\)、\(\{G_{1,1},G_{2,1},G_{3,1}\}\)、\(\{G_{1,3},G_{2,3},G_{3,3}\}\),直接看他们两两之间的差是否相等就行了,这里合法数列的数量要直接加在最终答案里面。

然后就是第二种,也容易发现有四种,分别是 \(\{G_{1,1},G_{2,2},G_{3,3}\}\)、\(\{G_{1,3},G_{2,2},G_{3,1}\}\)、\(\{G_{1,2},G_{2,2},G_{3,2}\}\)、\(\{G_{2,1},G_{2,2},G_{2,3}\}\),因为每组都有两个已经有了,所以中间数能直接求出来,但要看是不是整数,不是就表示这一组无法合法,然后将能合法的中间数的可能值统计出来,从中取出一个出现次数最多的。最后将两种情况的合法数列数量加在一起就是答案。

#include<bits/stdc++.h>
using namespace std;
int g[5][5];
bool check(int x,int y,int z){//判断三数是不是等差数列
   if(x-y==y-z)return 1;
   return 0;
}
map<int,int> mp;//统计出现次数
int main(){
   std::ios::sync_with_stdio(0);
   cin.tie(0),cout.tie(0);
   int T,id=0;
   cin>>T;
   while(T--){
      mp.clear();
      cin>>g[1][1]>>g[1][2]>>g[1][3];//输入
      cin>>g[2][1]>>g[2][3];
      cin>>g[3][1]>>g[3][2]>>g[3][3];
      int ans=0;
      ans+=check(g[1][1],g[1][2],g[1][3]);//枚举
      ans+=check(g[3][1],g[3][2],g[3][3]);
      ans+=check(g[1][1],g[2][1],g[3][1]);
      ans+=check(g[1][3],g[2][3],g[3][3]);
      if((g[2][1]+g[2][3])%2==0){//如果是正整数
         mp[(g[2][1]+g[2][3])/2]++;//统计答案
      }
      if((g[1][2]+g[3][2])%2==0){
         mp[(g[1][2]+g[3][2])/2]++;
      }
      if((g[1][1]+g[3][3])%2==0){
         mp[(g[1][1]+g[3][3])/2]++;
      }
      if((g[1][3]+g[3][1])%2==0){
         mp[(g[1][3]+g[3][1])/2]++;
      }
      int mx=0;
      for(auto d:mp){//枚举每个可能的答案
         mx=max(mx,d.second);//取出现次数最大的
      }
      cout<<"Case #"<<++id<<": ";
      cout<<ans+mx<<'\n';
   }
   return 0;
}
posted @ 2026-10-17 18:59  SCX2014  阅读(2)  评论(0)    收藏  举报