2014多校第五场1010 || HDU 4920 Matrix multiplication(矩阵乘法优化)

题目链接

题意 : 给你两个n*n的矩阵,然后两个相乘得出结果是多少。

思路 :一开始因为知道会超时所以没敢用最普通的方法做,所以一直在想要怎么处理,没想到鹏哥告诉我们后台数据是随机跑的,所以极端数据是不可能会有的,而我们一开始一直在想极端数据能接受的方法。。。。。。后来看了鹏哥的做法,就是把是0的地方都跳过就可以了,用矩阵保存前一个非0数的位置是多少。二师兄给我看了一个代码,人家根本没用别的优化,直接将最里层k的循环提到了最外层,然后就AC了,对此我表示无语。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4
 5 using namespace std ;
 6
 7 int a[810][810],b[810][810];
 8 int a1[810][810],b1[810][810] ;
 9 int c[810][810] ;
10
11 int main()
12 {
13     int n ;
14     while(~scanf("%d",&n))
15     {
16         memset(a,0,sizeof(a)) ;
17         memset(b1,0,sizeof(b1)) ;
18         memset(c,0,sizeof(c)) ;
19         memset(a1,0,sizeof(a1)) ;
20         memset(b,0,sizeof(b)) ;
21         for(int i = 1 ; i <= n ; i++)
22         {
23             for(int j = 1 ; j <= n ; j++)
24             {
25                 scanf("%d",&a[i][j]) ;
26                 a[i][j] %= 3 ;
27             }
28         }
29         for(int i = 1 ; i <= n ; i++)
30         {
31             for(int j = 1 ; j <= n ; j++)
32             {
33                 scanf("%d",&b[i][j]) ;
34                 b[i][j] %= 3 ;
35             }
36         }
37         for(int i = 1 ; i <= n ; i++)
38         {
39             int pre = -1 ;
40             for(int j = n ; j >= 0 ; j--)
41             {
42                 a1[i][j] = pre ;
43                 if(a[i][j])
44                     pre = j ;
45             }
46         }
47         for(int i = 1 ; i <= n ; i++)
48         {
49             int pre = -1 ;
50             for(int j = n ; j >= 0 ; j--)
51             {
52                 b1[i][j] = pre ;
53                 if(b[i][j])
54                     pre = j ;
55             }
56         }
57         for(int i = 1 ; i <= n ; i++)
58         {
59             for(int j = a1[i][0] ; j + 1 ; j = a1[i][j])
60             {
61                 for(int k = b1[j][0] ; k + 1 ; k = b1[j][k])
62                 {
63                     c[i][k] += a[i][j]*b[j][k] ;
64                 }
65             }
66         }
67         for(int i = 1 ; i <= n ; i++)
68         {
69             for(int j = 1 ; j <= n ; j++)
70             {
71                 printf("%d",c[i][j]%3) ;
72                 if(j != n)
73                     printf(" ") ;
74             }
75             printf("\n") ;
76         }
77     }
78     return 0 ;
79 }

看一下这个把k放在最外层的代码吧。。。。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 using namespace std;
 6 const int N = 805;
 7 int a[N][N], b[N][N], ans[N][N];
 8 int main()
 9 {
10     int n, i, j, k;
11     while(~scanf("%d",&n))
12     {
13         for(i = 1; i <= n; i++)
14             for(j = 1; j <= n; j++)
15             {
16                 scanf("%d",&a[i][j]);
17                 a[i][j] %= 3;
18             }
19         for(i = 1; i <= n; i++)
20             for(j = 1; j <= n; j++)
21             {
22                 scanf("%d",&b[i][j]);
23                 b[i][j] %= 3;
24             }
25         memset(ans, 0, sizeof(ans));
26         for(k = 1; k <= n; k++) //经典算法中这层循环在最内层,放最内层会超时,但是放在最外层或者中间都不会超时,不知道为什么
27             for(i = 1; i <= n; i++)
28                 for(j = 1; j <= n; j++)
29                 {
30                     ans[i][j] += a[i][k] * b[k][j];
31                     //ans[i][j] %= 3;   //如果在这里对3取余,就超时了
32                 }
33         for(i = 1; i <= n; i++)
34         {
35             for(j = 1; j < n; j++)
36                 printf("%d ", ans[i][j] % 3);
37             printf("%d\n", ans[i][n] % 3);
38         }
39     }
40     return 0;
41 }

2014多校第五场1010 || HDU 4920 Matrix multiplication(矩阵乘法优化),布布扣,bubuko.com

时间: 2024-10-16 06:10:45

2014多校第五场1010 || HDU 4920 Matrix multiplication(矩阵乘法优化)的相关文章

2014多校第五场1001 || HDU 4911 Inversion (归并求逆序数)

题目链接 题意 : 给你一个数列,可以随意交换两相邻元素,交换次数不超过k次,让你找出i < j 且ai > aj的(i,j)的对数最小是多少对. 思路 : 一开始想的很多,各种都想了,后来终于想出来这根本就是求逆序数嘛,可以用归并排序,也可以用树状数组,不过我们用树状数组做错了,也不知道为什么.求出逆序数来再减掉k次,就可以求出最终结果来了.求逆序数链接1,链接2 1 #include <stdio.h> 2 3 int left[250003], right[250003];

2014多校第六场 1010 || HDU 4930 Fighting the Landlords (模拟)

题目链接 题意 : 玩斗地主,出一把,只要你这一把对方要不了或者你出这一把之后手里没牌了就算你赢. 思路 : 一开始看了第一段以为要出很多次,实际上只问了第一次你能不能赢或者能不能把牌出尽. 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 5 using namespace std ; 6 7 char str1[20],str2[20] ; 8 int hash1[20],hash2[2

HDU 4920 Matrix multiplication(矩阵相乘)

各种TEL,233啊.没想到是处理掉0的情况就可以过啊.一直以为会有极端数据.没想到竟然是这样的啊..在网上看到了一个AC的神奇的代码,经典的矩阵乘法,只不过把最内层的枚举,移到外面就过了啊...有点不理解啊,复杂度不是一样的吗.. Matrix multiplication Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 640 

HDU 4920 Matrix multiplication 矩阵相乘。稀疏矩阵

Matrix multiplication Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1775    Accepted Submission(s): 796 Problem Description Given two matrices A and B of size n×n, find the product of them.

hdu 4920 Matrix multiplication(矩阵坑题)

http://acm.hdu.edu.cn/showproblem.php?pid=4920 被这道题虐了一下午,啥也不说了.继续矩阵吧. 超时就超在每步取余上,要放在最后取余,再者注意三个循环的次序. #include <stdio.h> #include <map> #include <set> #include <stack> #include <queue> #include <vector> #include <cma

hdu - 4920 - Matrix multiplication(缓存优化+开挂)

题意:求两个n x n的矩阵相乘后模3的结果,n <= 800. 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4920 -->>呀呀.. 1.3层计算的for进行缓存优化,根据CPU的L1级缓存的实现原理,减少缓存的变更.如果每次都计算完一个单元格的结果再计算下一个单元格的结果,那么被乘矩阵的访问就会频繁地更新缓存,使效率很低.. 2.输入开挂,G++提效500ms+.. 3.对乘法进行剪枝.. 没有第1个操作,后果是严重的.. n^3的

2014多校第十场1004 || HDU 4974 A simple water problem

题目链接 题意 : n支队伍,每场两个队伍表演,有可能两个队伍都得一分,也可能其中一个队伍一分,也可能都是0分,每个队伍将参加的场次得到的分数加起来,给你每个队伍最终得分,让你计算至少表演了几场. 思路 : ans = max(maxx,(sum+1)/2) :其实想想就可以,如果所有得分中最大值没有和的一半大,那就是队伍中一半一半对打,否则的话最大的那个就都包了. 1 #include <cstdio> 2 #include <cstring> 3 #include <st

2014多校第七场1005 || HDU 4939 Stupid Tower Defense (DP)

题目链接 题意 :长度n单位,从头走到尾,经过每个单位长度需要花费t秒,有三种塔: 红塔 :经过该塔所在单位时,每秒会受到x点伤害. 绿塔 : 经过该塔所在单位之后的每个单位长度时每秒都会经受y点伤害. 蓝塔 : 经过该塔所在单位之后,再走每个单位长度的时候时间会变成t+z. 思路 : 官方题解 : 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #define LL long long

2014多校第六场 1005 || HDU 4925 Apple Tree

题目链接 题意 : 给你一块n×m的矩阵,每一个格子可以施肥或者是种苹果,种一颗苹果可以得到一个苹果,但是如果你在一个格子上施了肥,那么所有与该格子相邻(指上下左右)的有苹果树的地方最后得到的苹果是两倍,如果(i,j)有一颗苹果树,(i-1,j)与(i,j+1)施了肥,那么苹果应该是1的两倍2,2的两倍4,最后是4个苹果,问你怎么安排苹果和施肥的格子使最后得到的苹果最多. 思路 : 画了图就可以看出来,苹果和苹果,肥与肥之间不要相邻就好了,所有的苹果之间都有施肥,所有施肥的格子都被苹果隔开了才能