2321. 【NOIP普及组T1】方程
时间限制:
1000 ms 空间限制: 262144 KB
题解:
这一道题就是一道模拟题。
首先我们要知道,如果你知道了第一个人的性别,你就一定可以推出第二个,然后再推出第三个,第四个……
所以,我们只需要分男和女讨论第一个人的性别,就可以一直推到最后一个。
这时,我们只需要在推的过程中加入一些判断,看看是否合法,不合法就做一个标记并跳出。
如果合法,则ans++。
这道题的大体思路就是这样的。
注意:
每做完一次顺推后,都要初始化一下,不然的话…………
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,a[300001],s[300001],b[300001],ans=0,p=1,t; 4 //s为每个人的性别(1为男,0为女),a为周围男生数,b为进行操作的数组,p储存方案是否合法 5 void doit(int q) 6 { 7 for(int i=q;i<=n;i++) 8 { 9 b[i]-=s[i-1]+s[i];//由前两个推出第三个 10 if(b[i]==1) 11 { 12 if(i==n)//如果后面没有任何人而还要有一个人,则不合法 13 { 14 p=0;//做标记 15 break; 16 } 17 s[i+1]=1;//推出第三个为男生 18 } 19 if(b[i]>=2||b[i]<0)//如果i+1位置需要2个及以上或0个及一下,则不合法 20 { 21 p=0;//做标记 22 break; 23 } 24 } 25 } 26 int main() 27 { 28 scanf("%d",&t); 29 while(t!=0) 30 { 31 t--; 32 scanf("%d",&n); 33 for(int i=1;i<=n;i++) 34 { 35 scanf("%d",&a[i]); 36 b[i]=a[i];//预处理备用数组b。 37 } 38 s[1]=1;//先尝试1可不可行 39 doit(1); 40 if(p!=0)//如果可行 41 ans++; 42 for(int i=1;i<=n;i++) 43 { 44 s[i]=0; 45 b[i]=a[i]; 46 } 47 p=1; 48 //做完了要回到做之前的时候的状态 49 //s[1]=0; //由于我们在上面已经将s数组初始化为0,所以不用再写 50 doit(1);//尝试0可不可行 51 if(p!=0)//如果可行 52 ans++; 53 printf("%d\n",ans); 54 for(int i=1;i<=n;i++) 55 { 56 s[i]=0; 57 b[i]=a[i]; 58 } 59 p=1; 60 ans=0; 61 //再为下一次进行初始化 62 } 63 return 0; 64 }
所以……就是这样!
做完了!