-
错误的算法
- 时间限制: 5000 ms 内存限制: 65535 K
- 问题描述
-
有道题目是这样的:
输入一个 n 行 m 列网格,找一个格子,使得它所在的行和列中所有格子的数之和最大。如果答 案不唯一,输出任意解即可。比如,在下面的例子中,最优解是(1,3),即第一行和的三列的交 点(行从上到下编号为 1~n,列从左到右编号为 1~m),所有 7个数之和为 35。
快要比赛的时候,有一个裁判想到了这样一个算法:
首先找一行 r(1<=r<=n) 使得该行所有数之和最大,然后找一列 c(1<=c<=m) 使得该列 所有数之和最大,最后直接输出(r,c)。如果有多个满足条件的 r,输出最小的 r。对 于 c 同样处理。
显然,这个算法是错的,但它竟然通过了大部分测试数据!你能找出那些让这个错误算法得到 正确结果的“弱”数据,以便裁判们改进这些数据吗?
- 输入
-
输入包含不超过 100 组数据。每组数据第一行为两个整数 n, m (1<=n<=500, 1<=m<=500),即行 数和列数。以下 n 行每行包含 m 个 1~100 的整数。输入的总大小不超过 2MB。
- 输出
-
对于每组数据,如果错误算法能得到正确结果,输出"Weak",否则输出"Strong"。
- 样例输入
-
4 4 5 5 5 5 1 1 5 1 1 1 5 1 1 1 5 1 5 4 2 5 1 1 1 1 9 1 1 1 1 1 1 1 1 1 1 1 1 1
- 样例输出
-
Case 1: Weak Case 2: Strong
- 提示
-
无
- 来源
-
第十一届“蓝狐网络杯”湖南省大学生计算机程序设计竞赛
#include<cstdio> #include<cstring> #include<iostream> #include<cmath> using namespace std; #define maxn 510 int a[maxn][maxn],b[maxn],c[maxn],d[maxn][maxn]; int main() { int n,m,num = 0; while(cin >> n >> m){ num ++; memset(b,0,sizeof(b)); memset(c,0,sizeof(c)); for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cin >> a[i][j]; b[i] += a[i][j];//计算每一行的值的和 c[j] += a[i][j];//计算每一列的值的和 } } int x,y,maxc = 0; for(int i=0;i<n;i++){//查找和是最大值的行,记录错误计算的答案的行数 if(maxc < b[i]){ maxc = b[i]; x = i; } } maxc = 0; for(int j=0;j<m;j++){//查找和是最大值的列,记录错误计算的答案的列数 if(maxc < c[j]){ maxc = c[j]; y = j; } } maxc = 0; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ d[i][j] = b[i] + c[j] - a[i][j]; //计算正确计算的答案,行数和加列数和减去重复计算的行列交点的数值 if(maxc < d[i][j]){ maxc = d[i][j]; //计算出正确计算的答案的值 } } } int flag = 0; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ if(d[i][j] == maxc){//正确计算的答案可能有多个,只要符合即开始查找 if(x==i && y==j){//查找如果正确计算的答案的横纵坐标与错误计算的答案的横纵坐标完全相同,则匹配成功,做上标记并从循环中跳出 flag = 1; break; } } } } if(flag){ cout << "Case " << num << ": Weak" << endl; } else cout << "Case " << num << ": Strong" << endl; } return 0; }