看完题立刻想到了对3取模,分别判断0/1。
然而想到了之前草率提交,掉分的惨痛经历,于是打算多进行几次演算,做一下充分性证明。
观察到d(a1,a2,a3)=abs(a1+a3-2*a2),想到:是否可以将(a1+a3)视为一个"整体"(num1),(2*a2)视为另一个"整体"(num2),最小化两者的差值。
考虑到每次从num1取值递给num2,实际上都是num-1,num2+2,abs(num1-num2)的实际改变值为3,那么只要abs(num1-num2)对3取模就获取了不能传递的剩余值。
错误数据:1 1 3(num1:4,num2:2)
但实际上,这种算法少考虑了一种情况:如果abs(num1-num2)的值为2,实际上这代表可以做一次传递,使得结果为1。
方法1:推理证明
#include<cstdio> #include<iostream> #include<cmath> using namespace std; int main(){ int t; scanf("%d",&t); while(t--){ int a,b,c; scanf("%d%d%d",&a,&b,&c); int num1=a+c,num2=b*2; int rest=abs(num1-num2)%3; if(rest==2)rest=1; printf("%d\n",rest); } return 0; }
方法2:直觉
#include<cstdio> #include<iostream> #include<cmath> using namespace std; int main(){ int t; scanf("%d",&t); while(t--){ int a,b,c; scanf("%d%d%d",&a,&b,&c); int sum=a+b+c; if(sum%3==0){ printf("0\n"); }else{ printf("1\n"); } } return 0; }