SJTU OJ 1228 Matrix Sum
来源:互联网 发布:淘宝上的代练 编辑:程序博客网 时间:2024/06/07 10:40
SJTU OJ 1228 Matrix Sum
原题链接
这道题做法不唯一,这里只写一个我第一次做时想出来的一个方法。
首先令所有奇数为1,所有偶数为0。假定一个单行的矩阵,比如是00101100011101,数其中和为奇数的子矩阵个数。我们发现连续的0取其中不论几个都不影响奇偶。假设有n个连续的0,那么可以取0~n一共n+1种情况。当矩阵只含有第一个1时,两侧的0的取法有3*2=6种。当矩阵含有前三个1时,有3*4=12种。可以发现规律。
但是子矩阵不一定单行,所以就把位置靠下的行并到上面的某一行(不妨仍然奇数为1偶数为0),然后同上操作这一行。
下面是代码:
#include <iostream>#include <cstdio>using namespace std;long long, re1 = 0, re2 = 0;//re1奇数re2偶数;int store_zero[405];//存储每一串0的取法;int work[405];//每次操作的那一行;int len = 0;//实时为store_zero[]的有效长度;int arr[405][405] = {0};void count_it(){ int now = 0; for (int i=0; i<n; i++){ now++; if (work[i] == 1){ store_zero[len++] = now; now = 0; } } if (len == 0) return;//没有1; store_zero[len++] = ++now; for (int i=0; i<len; i++){ for (int j=i+1; j<len; j+=2){ re1 += (store_zero[i] * store_zero[j]); } } len = 0; return;}int main(){ scanf("%d", &n); int d; for (int i=0; i<n; i++){ for (int j=0; j<n; j++){ scanf("%d", &d); arr[i][j] = d%2; } } for (int i=0; i<n; i++){//从第几行开始; for (int j=0; j<n; j++){//先把这一行赋给work[]; work[j] = arr[i][j]; } count_it(); for (int j=i+1; j<n; j++){//再把下面的行依次加到work[]; for (int k=0; k<n; k++){ work[k] = (work[k]+arr[j][k])%2; } count_it(); } for (int j=0; j<n; j++){//work[]清零; work[j] = 0; } } re2 = n*n*(n+1)*(n+1)/4 - re1;//子矩阵总数n*n*(n+1)*(n+1)/4; cout << re1 << ' ' << re2; return 0;}
还有复杂度更低的算法,欢迎指教。
阅读全文
0 0
- SJTU OJ 1228 Matrix Sum
- SJTU OJ.1204
- SJTU OJ.1204_new
- 【数据结构】SJTU OJ 1237
- 【数据结构】SJTU OJ 1233
- 【数据结构】SJTU OJ 1234
- SJTU OJ 3008 Maze
- sjtu oj 1022. Fib数列
- SJTU OJ 1006 求和游戏
- SJTU OJ 1012. 增长率问题
- SJTU OJ 1006. 求和游戏
- sjtu
- sjtu oj 1002.二哥种花生
- sjtu oj 1003.二哥养细菌
- sjtu oj 1008.二哥买期货
- sjtu oj 1036. 二哥去取钱
- SJTU OJ 1990 二哥听CD
- SJTU OJ 1558 最长序列问题
- jvm栈帧结构
- pytho入门第一天——函数
- React 使用技巧总结 <二>
- SSM(4)前端+后端传输格式验证
- Linux后台作业
- SJTU OJ 1228 Matrix Sum
- 求解两个字符串的最长公共子序列
- POJ 1833 排列
- java 网络编程三要素之ip地址
- Github的清点对象算法
- 队列的基本操作及实现
- Python Machine Learning 1 普通最小二乘法
- 浅谈SSM框架
- 8.7 数字格式化(Formatter类)