做法:
使用我初赛前颓膜时的做法,重循环枚举。
但是显然这样是过不了的,因为有。
像膜里那样只能取范围内的数这样多好
做法:
枚举。
对于每组,可以得到的值。
具体地,
注:有一个运算法则:
之后对于每个,求出对应的两个。
具体地,
只要某一个同时在所有的组里出现,就可以作为答案的一部分,也就是说有一组符合条件,就可以加一。这可以用计数数组实现,但也可以一通乱搞(比如我就是这么做的)。
具体见代码:
//这是我比赛时现场写的代码,所以有些变量名称取得不是很好,请见谅
#include <bits/stdc++.h>
using namespace std;
#define N 111111
inline int read(){
int x=0,f=1;
char c=getchar();
while (c<'0' || c>'9'){
if (c=='-') f=-1;
c=getchar();
}
while (c>='0' && c<='9'){
x=x*10+c-48;
c=getchar();
}
return x*f;
}
int x[N],y[N],z[N],b[N];
int main(){
int n=read(),m=read();
for (int i=1;i<=n;++i){
x[i]=read(),y[i]=read(),z[i]=read();
}
int ans=0;
for (int i=1;i<=m;++i){
for (int j=1;j<=m;++j){
int dimc=-1,dimd=-1; //dimc和dimd是用来找那个在每组都出现过的z的
for (int k=1;k<=n;++k){
int b,c,d;
b=9^(abs(i-x[k])^abs(j-y[k])); //求出对应的|ci-z|
c=z[k]+b; //求出|ci-z|=b的两个根
d=z[k]-b;
if (c>m) c=-2; //如果根不符合条件就舍去
if (d<=0) d=-2;
if (k==1){
if (c!=-2) dimc=c;
if (d!=-2) dimd=d;
}else{
if (c==dimc && d==dimd){ //一通乱搞看看这两个根在之前有没有一直在出现,如果没有就不要这个根了
continue;
}else if (c==dimd && d==dimc){
continue;
}else if (c==dimc){
dimd=-1;
}else if (c==dimd){
dimc=-1;
}else if (d==dimc){
dimd=-1;
}else if (d==dimd){
dimc=-1;
}else{
dimc=dimd=-1;
}
}
}
if (dimc!=-1) ans++;
if (dimd!=-1 && dimc!=dimd) ans++; //如果有可行的根,那么对答案增加贡献
}
}
cout<<ans<<endl;
return 0;
}
最后来一波宣传:
长期更新:膜Siyuan攻略
话说这次比赛之后膜的人明显多了啊
作为一个初赛前就将膜真理V
搞定的玩家,我有必要发一点关照新手的攻略
顺便改版了LMOliver
的Game
,并更新了超出膜的一小部分内容