ZOJ3180 Number Game
要点:
判断后三个数字能否通过上述的变换过程 推出前三个数字 ,我们可以逆向思维考虑 也就是逆着推回去
如果符合后三个数字 或其变换一次的数字(即符合其中一种组合形式) ,则输出yes
其中重要的点: 要将这些数字从小到大排序,便于比较判断, 前三个数字即使不断减小的但也不能小于或等于0
给出代码如下:(有部分注释)
#include<iostream> #include<algorithm> using namespace std; const int N = 4; int main() { int a[N], b[N]; int t; cin >> t; while(t--) { for(int i = 0; i < 3; i++) { cin >> a[i]; } for(int i = 0; i < 3; i++) { cin >> b[i]; } int dp[N][N]; dp[0][0] = b[0]; dp[0][1] = b[1]; dp[0][2] = b[2]; dp[1][0] = b[1] + b[2] - 1; dp[1][1] = b[1]; dp[1][2] = b[2]; dp[2][0] = b[0]; dp[2][1] = b[0] + b[2] - 1; dp[2][2] = b[2]; dp[3][0] = b[0]; dp[3][1] = b[1]; dp[3][2] = b[0] + b[1] - 1; for(int i = 0; i < 4; i++) { sort(dp[i], dp[i] + 3);//将每种情况按从小到大排序 } while(1)//因为不知道要将前三个数字变换多少次才能推回到原来的数字 { int flag ; sort(a, a+3);//每次都将这三个数按从小到大排序 ,便于比较 for(int i = 0; i < 4; i++) { flag = 1; for(int j = 0; j < 3; j++) { if(dp[i][j] != a[j]) { flag = 0; } } if(flag) { break; } } if(flag) // 只有三个数符合dp中任何一种情况时,才能确保输出yes; { cout << "Yes" << endl; break; } if(a[1] - a[0] + 1 == a[2])// 陷入死循环, 并且这三个数不符合dp的任何一种情况 { cout << "No" << endl; break; } else { a[2] = a[1] - a[0] + 1; flag = 1; for(int i =0 ; i < 3; i++)//逐渐逆推回去的过程中,还没到符合情况就已经有负数出现 { if(a[i] <= 0) { flag = 0; } } if(flag == 0) { cout <<"No" << endl; break; } } } } return 0; }