HDOJ Kiki & Little Kiki 2 2276【位运算+矩阵快速幂】
来源:互联网 发布:linux删除文件夹还存在 编辑:程序博客网 时间:2024/06/07 04:59
Kiki & Little Kiki 2
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2213 Accepted Submission(s): 1137
Change the state of light i (if it's on, turn off it; if it is not on, turn on it) at t+1 second (t >= 0), if the left of light i is on !!! Given the initiation state, please find all lights’ state after M second. (2<= n <= 100, 1<= M<= 10^8)
If the ith character of T is '1', it means the light i is on, otherwise the light is off.
1010111110100000001
1111000001000010
观察: 最后一个数字变化 01 -->?1 10-->?1 11-->?0 00-->?0 观察到最后一位的结果是 这两个数字异或的结果。 事实是第i位数字的结果就是 第i位异或i-1位。
所以判断第i位就是取出第i位和i-1位,然后进行异或运算。如何取出这两位?让与这两位相乘的数字等于1 ,其他位上相乘的数字等于0 例如0101000取出2 3位 就是与0110000 相乘 我们已经学会如何取出i位和i-1位上的两个数字 然后如何判断第i位的值呢? 其实异或的运算结果就等于数字相加mod 2 的结果。0^1=(0+1)%2=1
1^1=(1+1)%2=0 0^0=(0+0)%2=0 1^0=(1+0)%2=1
所以当我们取出i位i-1位之后可以进行相加对2取余 得到第i位的结果。
题目给的第一个样例如果:
取第1 2位则相乘的数字 1 1 0 0 0 0 0
取第2 3位则相乘的数字 0 1 1 0 0 0 0
取第3 4位则相乘的数字 0 0 1 1 0 0 0
取第4 5位则相乘的数字 0 0 0 1 1 0 0
取第5 6位则相乘的数字 0 0 0 0 1 1 0
取第6 7位则相乘的数字 0 0 0 0 0 1 1
取第7 1位则相乘的数字 1 0 0 0 0 0 1
如果是一秒后的状态就每一位都取一次 就是乘以上述矩阵一次,2秒后的状态就是乘以矩阵两次。。。。。m秒后的状态就是乘以m次。
所以可以转化成矩阵的快速幂 指数为m。然后用给定的字符串再去乘以该矩阵 得到的结果就是m秒后的状态
注意矩阵相乘时的优化。否则超时。
AC代码
#include <stdio.h>#include <string.h>#include <algorithm>#define maxn 100+5using namespace std;int mat[maxn][maxn];int res[maxn][maxn];int n,m;void Matmul(int x[maxn][maxn],int y[maxn][maxn],int Mod){int t[maxn][maxn];memset(t,0,sizeof(t));/*第一种 计算每一个位置上的元素。 //这样计算没法优化,会超时for(int i=0;i<n;i++)for(int j=0;j<n;j++)for(int k=0;k<n;k++)t[i][j]=(t[i][j]+x[i][k]*y[k][j])%Mod;*//*第二种 一行一行的计算出所有元素 for(int i=0;i<n;i++)for(int k=0;k<n;k++)if(x[i][k]) //剪枝优化 for(int j=0;j<n;j++)t[i][j]=(t[i][j]+x[i][k]*y[k][j])%Mod;*///第三种 一列一列的计算出所有元素for(int j=0;j<n;j++)for(int k=0;k<n;k++)if(y[k][j]) //剪枝优化 for(int i=0;i<n;i++)t[i][j]=(t[i][j]+x[i][k]*y[k][j])%Mod;for(int i=0;i<n;i++)for(int j=0;j<n;j++)x[i][j]=t[i][j];}void init_res(){for(int i=0;i<n;i++)for(int j=0;j<n;j++)res[i][j]=(i==j);}void Matrix(int a[maxn][maxn],int n,int Mod){init_res();while(n){if(n&1)Matmul(res,a,Mod);Matmul(a,a,Mod);n>>=1;}}int main(){char s[110];int ans[110];while(scanf("%d",&m)!=EOF){memset(mat,0,sizeof(mat));memset(res,0,sizeof(res));scanf("%s",s);n=strlen(s);for(int i=0;i<n;i++)ans[i]=s[i]-'0';for(int i=0;i<n-1;i++) //给出初始矩阵 mat[i][i]=mat[i][i+1]=1;mat[n-1][0]=mat[n-1][n-1]=1;Matrix(mat,m,2);int temp[110]={0};for(int i=0;i<n;i++){for(int j=0;j<n;j++){temp[i]=(temp[i]+ans[j]*res[j][i])%2;}}for(int i=0;i<n;i++)printf("%d",temp[i]);printf("\n");}return 0;}
- HDOJ Kiki & Little Kiki 2 2276【位运算+矩阵快速幂】
- hdoj 2276 Kiki & Little Kiki 2【矩阵快速幂】
- HDU 2276 Kiki & Little Kiki 2 (位运算+矩阵快速幂)
- HDU 2276-Kiki & Little Kiki 2(矩阵快速幂+位运算)
- hdu 2276 Kiki & Little Kiki 2(矩阵快速幂)
- HDU 2276 Kiki & Little Kiki 2 矩阵快速幂
- HDU 2276 Kiki & Little Kiki 2(矩阵快速幂)
- hdu 2276 Kiki & Little Kiki 2 (矩阵快速幂)
- HDU - 2276 Kiki & Little Kiki 2 矩阵快速幂
- HDU 2276 Kiki & Little Kiki 2(矩阵快速幂)
- hdu 2276 Kiki & Little Kiki 2矩阵快速幂
- HDU 2276 Kiki & Little Kiki 2 (矩阵快速幂)
- hdu 2276 Kiki & Little Kiki 2 矩阵快速幂
- HDU2276 - Kiki & Little Kiki 2(矩阵快速幂)
- nyoj--300 Kiki & Little Kiki 2(矩阵快速幂)
- HDU2276 Kiki & Little Kiki 2 矩阵快速幂
- nyoj 300 (矩阵快速幂)Kiki & Little Kiki 2
- Kiki & Little Kiki 2(矩阵快速幂(推理))
- [sublime]安装插件配置lua
- android Log.isLoggable方法的使用
- iOS多线程
- ionic 项目中使用ngCordova插件$cordovaCamera筛选手机图库图片显示出来并上传
- 文章标题
- HDOJ Kiki & Little Kiki 2 2276【位运算+矩阵快速幂】
- 手机网页摇一摇问题
- 关于坚持与凝聚力
- Hdoj 3790 最短路径问题
- QT 总结(一)(1.某位设1或0 2.加载dll、lib库 3.char * 转换为 wchar_t * 4.textBrowser 显示乱码 追加 5.checkBox的使能)
- hdu 5361 2015多校联合训练赛#6 最短路
- Java IO流--字符流
- Learning!数组|Array
- Curl状态码列表