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;
}

浙公网安备 33010602011771号