POJ1166

来源:互联网 发布:淘宝双十一活动策划书 编辑:程序博客网 时间:2024/06/06 13:01

这道题目和1830比较类似,1830是求解的个数,这道题目相当于求线性方程组的整数解(注意,这道题目的陷阱之一就是解出来的结果可能不是整数,反正我的代码一开始就是有的是小数)

题目主要内容:有9个钟,其中9个操作方法来扳动上面的指针,每个操作每次只能把指针移动90度,且每个操作是对一组钟进行操作(即执行每个操作之后有几个钟的状态被改变了90度而不是单独某个钟的状态改变了90度)。操作与其影响的钟的对应表如表一所示:


表一

题目要求的是给出这9个钟的初始状态(0表示指向12点,1表示指向3点,2表示指向6点,3表示指向6点)用操作1-9采用最少的移动次数操作这些钟,使它们都指向12点。

思路:根据操作与钟表的关系我们可以构造一个关系矩阵,如表二所示


行表示钟,列表示操作,例如,操作1,2,4被采用之后A都会受到影响,移动一步(即90度)。所以题目的意思就是求操作1-9都被操作了多少次,使得每个钟表从初始状态被调整到12点的那个状态,即每个钟表的状态变化=操作1*操作次数+操作2*操作次数+…+操作9*操作次数。


用测试数据作为例子说明一下:


但是注意,1-9操作的次数并不是这道题目的输出结果,它要求咱们把每个操作的过程输出来,也就是如果我操作了2次9号操作那么就输出9 9。还是看测试数据,虽然求出来的结果是


但是输出的结果是4,5,8 ,9

(这里之前卡了一下,一开始我以为操作出现的顺序会影响钟表的状态,但是仔细想一下发现操作的出现次序与钟表的最后状态没关系,即操作顺序 1  3   1与操作1   1   3是一样的,若有疑问可以自己模拟操作一下。所以只需要求出每个操作的操作次数,从小到大把次数对应的操作序号输出就可以了。)

陷阱1:求解出线性方程组的解的时候,有的时候出现非整数解的情况,这说明按这个数移动是最小的移动数,但是操作不了,那我们只能不断地再状态变化上面再加上一轮(即4)使得求得的数是整数。

陷阱2:求解出的解释负数,即往负方向转能更快到达12点的状态,但是题目里没有说可以用负方向转的,所以只能在其上面不断的加上一轮使得移动的次数变成正数。

代码:

#include<iostream>#include<cmath>using namespace std;int a[9][9]={{1,1,0,1,0,0,0,0,0},{1,1,1,0,1,0,0,0,0},{0,1,1,0,0,1,0,0,0},{1,0,0,1,1,0,1,0,0},{1,0,1,0,1,0,1,0,1},{0,0,1,0,1,1,0,0,1},{0,0,0,1,0,0,1,1,0},{0,0,0,0,1,0,1,1,1},{0,0,0,0,0,1,0,1,1}};float b[9][10];void convert(int n,int m){int i,j,t,swapline,tag,time;float mul,cal[10];for(i=0;i<n;i++){//找到不为0的那行;for(j=i;j<n;j++){if(b[j][i]!=0)break;}//若当前要处理的行的位置等于0,那么把不等于0的与它交换if(j<n){if(j!=i){swapline=j;for(j=i;j<m;j++){t=b[swapline][j];b[swapline][j]=b[i][j];b[i][j]=t;}}//将子矩阵处理成第一列为0 的for(j=i+1;j<n;j++){tag=0;if(b[j][i]!=0){mul=-b[i][i]/b[j][i];for(t=i;t<m;t++){b[j][t]=mul*b[j][t]+b[i][t];}}}}}for(j=0;j<n;j++){tag=0;for(t=j;t<m;t++){if((int)b[j][t]!=b[j][t])tag=1;}if(tag){time=2;while(tag){tag=0;for(t=j;t<m;t++){cal[t]=b[j][t]*time;if((int)cal[t]!=cal[t])tag=1;}time++;}for(t=j;t<m;t++)b[j][t]=cal[t];}}}int main(){int s[9];float result[9],sum,rl,right;int i,j,t,time,tp;for(i=0;i<9;i++)for(j=0;j<9;j++)b[i][j]=a[i][j];for(i=0;i<9;i++){scanf("%d",&t);s[i]=(4-t)%4;b[i][9]=s[i];}convert(9,10);for(i=8;i>=0;i--){sum=0;for(j=8;j>i;j--){sum+=result[j]*b[i][j];}time=0;rl=0.1;while((int)rl!=rl){right=b[i][9]-sum+4*time;rl=right/(b[i][i]);time++;}time=1;while(rl<0){rl+=time*4;}result[i]=(int)rl%4;}for(i=0;i<9;i++){if(result[i]>0){for(j=0;j<result[i];j++)printf("%d ",i+1);}}return 0;}


原创粉丝点击