4.求解线性方程组【算法赛】 - 蓝桥云课 (lanqiao.cn)
题目说了xi只有0,1两种选择,那么ai只可能有0,1,2三种状态,我们对这三种状态分类讨论即可。
这道题是个递推题,观察题目我们发现一个规律:从a[2]开始,后面都是 的形式(除了a[n]),因此我们只需要通过推出来x[1],x[2]的值,知道了x[1],x[2]的值我们就可以通过推出x3的值,剩下的x[i]可以用推x[3]的方式递归,循环推出。
接下来我们就考虑怎么推出来x[1],x[2]。
因为题目说了x[]数组只能由0,1两种数组成,而题目又告诉了我们a[i]的值,因此x1,x2有下面几种可能:
当a[1]=2时
当x1,x2=0的情况
当x1,x2=1的情况
当a1=1时
当x1=0,x2=1的情况
当x1=1,x2=0的情况
针对每一种情况我们都可以往后推出一种解。现在我们需要对每一组解都推出x3,然后推x[i]。
x[3]:
x[i]:
code
#include<iostream>
using namespace std;
const int N = 2e5+10;
int n;
int a[N],x[N],b[N];
void op()
{
for (int i = 3; i < n; i++)
{
x[i + 1] = a[i] - x[i] - x[i - 1];
}
}
void sovel()
{
cin >> n;
for (int i = 1; i <= n; i++)cin >>a[i];
if (a[1] == 2)x[1] = x[2] = 1; //因为x[i]只有1,0,两种可能,所以a[i]最大只能为2
if (a[1] == 0)x[1] = x[2] = 0;
x[3] = a[2] - a[1];
//从这以后就可以循环递推了
if (a[1] == 1) //a[1]=1的话有两种可能
{
//第一种可能
x[1] = 0;
x[2] = 1;
op(); //由 0 1开头产生的递推
for (int i = 1; i <= n; i++)
{
b[i] = x[i - 1] + x[i] + x[i + 1]; //存储一下我们递推的结果
//如果说我们递推出来的b数组和a数组不一样,或者递推出来x[i]是负数(负数不可能和另一个数相加为1),那么说明不是0 1开头的这组解
if (b[i] != a[i] || x[i] < 0)
{
//那么我们就要递推另一种解
x[1] = 1;
x[2] = 0;
op(); //由 1,0开头产生的递推
break;
}
}
}
for (int i = 1; i <= n; i++)cout << x[i] << " ";
}
int main()
{
cin.tie(nullptr)->sync_with_stdio(false);
int t=1;
while(t--)
sovel();
return 0;
}